Hi list,<br><br>Could someone explain why the error pointed out by Luke occurred?<br><br><div class="gmail_quote">From: <b class="gmail_sendername">Luke Palmer</b> <span dir="ltr"><<a href="mailto:lrpalmer@gmail.com">lrpalmer@gmail.com</a>></span><br>
<br>I think this would be a very good question for the list. Don't worry,<br>
they're nice helpful folks.<br>
<br>
On Mon, Feb 14, 2011 at 10:10 PM, Alexander McPhail<br>
<div><div></div><div class="h5"><<a href="mailto:haskell.vivian.mcphail@gmail.com">haskell.vivian.mcphail@gmail.com</a>> wrote:<br>
> Hi Roman,<br>
><br>
><br>
> Can you explain why the following code doesn't work? 'unsafePerformIO' is<br>
> used all the time in hmatrix. For example, adding two vectors, we create a<br>
> new Vector then use that as the target for an FFI C call.<br>
><br>
> Is the difference because I'm using mutable Storable Vectors? I would have<br>
> thought that unsafeFreeze (at the end) would make sure the problem reported<br>
> by Luke wouldn't occur.<br>
><br>
> Is there a problem with laziness in the let binding of Luke's example?<br>
><br>
> I note that in Data.Vector.Storable there is a pure 'convert' function,<br>
> which is essentially what I am trying to emulate.<br>
><br>
> -- | convert to a vector<br>
> toVector :: Storable a => Buffer a -> (V.Vector a)<br>
> toVector (B o n v) = unsafePerformIO $ do<br>
> w <- M.new n<br>
> i <- readIORef o<br>
> M.unsafeWith v $ \p -><br>
> M.unsafeWith w $ \q -> do<br>
> let n' = n-i<br>
> copyArray q (p `advancePtr` i) n'<br>
> if i /= 0<br>
> then copyArray (q `advancePtr` n') p i<br>
> else return ()<br>
> V.unsafeFreeze w<br>
> {-# INLINE toVector #-}<br>
><br>
><br>
> Vivian<br>
><br>
> From: Luke Palmer <<a href="mailto:lrpalmer@gmail.com">lrpalmer@gmail.com</a>><br>
><br>
> This interface is an outlaw.<br>
><br>
> main = do<br>
> buf <- newBuffer 10 :: IO (Buffer Int)<br>
> pushNextElement buf 1<br>
> let v1 = V.toList (toVector buf)<br>
> v2 = V.toList (toVector buf)<br>
> print v1<br>
> pushNextElement buf 2<br>
> print v2<br>
><br>
> Despite v1 and v2 being defined to equal the exact same thing, this<br>
> program prints two distinct lines.<br>
><br>
> toVector depends on the current state of the buffer. If this is to be<br>
> a law-abiding interface, toVector must return a value in IO:<br>
><br>
> toVector :: (Storable a) => Buffer a -> IO (Vector a)<br>
><br>
> Luke<br>
><br clear="all"></div></div></div>