[Haskell-cafe] Mutable arrays

Jonathan Cast jonathanccast at fastmail.fm
Wed Feb 6 21:05:23 EST 2008


On 6 Feb 2008, at 11:56 AM, Chaddaï Fouché wrote:

> 2008/2/6, Jeff φ <jeff1.61803 at gmail.com>:
>> I have solved both of these problems in Clean using a lazy list  
>> without
>> resorting to unsafe operations.  So, it seems to me that  
>> uniqueness types
>> are more general than monads.
>
>  Are you aware that your code in Clean has some issues, like the lst
> not being so lazy if you operate on ary2 before you operate on lst (it
> is completely put in memory in this case) ? You've effectively created
> a big uncertainty on the space taken by your function. Is this ok with
> you ? The monadic fold (like I and some others proposed) guarantee you
> a constant amount of memory consumed and is perfectly safe too, is the
> Clean solution really so much better ?
>
> Jonathan Cast :
>> I'm confused --- does uToList_2D return the head of the list  
>> before or after it finishes reading
>> the array?  If before, then I don't see how the type system  
>> prevents me from modifying the
>> array before I finish examining the list, as you claim.  If after,  
>> then the list isn't truly lazy.
>
> What happens here is that the array can't be modified without
> evaluating ary2 and ary2 can't be evaluated without completely
> evaluating the list before,

I see.  I would agree that Clean's system is more powerful (and  
concomitantly more dangerous) in this case.

> so you effectively get the list lazily as
> long as you don't touch ary2 before touching the list, and you can't
> damage the list by modifying the array (because in this case, lst
> would be completely evaluated in the first place). You can do the same
> in Haskell in fact, but you'll need to discipline yourself to evaluate
> the "witness" before modifying the array.
>
>
> So uniqueness here seems to have an advantage over monads,

True.

> still, the
> monads look much cleaner (sic)

Some might argue this.

> than Clean code with all those unique
> value passing around...

The same thing could be implemented in Haskell, of course:

data MySafeArray a i e = MSA{
   touchThisFirst :: IORef (),
   realArray :: a i e
   }
instance MArray a e IO => MArray (MySafeArray a) e IO where
   unsafeRead a i = do
     x <- readIORef $ touchThisFirst a
     eval x
     touchThisFirst a `writeIORef` ()
     unsafeRead $ realArray a

Then your getContents looks like this:

getArrayElems a = do
   x <- readIORef $ touchThisFirst a
   eval x
   ls <- <get elements unsafely>
   touchThisFirst  a `writeIORef` deepSeq ls
   return ls

Ugly, but it can be encapsulated in a library somewhere.

jcc



More information about the Haskell-Cafe mailing list