Brian Hulley brianh at metamilk.com
Fri May 26 05:50:50 EDT 2006

```Dear friends -

Matthew Bromberg wrote:
> Not only does your suggestion make more sense than what I was doing,
> but also
> it causes the 'matrices' to behave as expected, namely to have the
> side effects
> incorporated into their array values.
>
> I can't say I fully understand why this is true.  In both cases I was
> wrapping Rmatrix in
> a monad after every computation.  The difference is that the array
>
> old case
> newtype Rmatrix = Rmatrix (Int, Int,  IO(StorableArray Int CDouble))
>
> new case
> newtype Rmatrix = Rmatrix (Int, Int,  StorableArray Int CDouble)
>
> In the old way, the additional IO wrapper forces an additional
> nesting of do loops for most processing.

This is the essential difference, but I think you haven't quite
understood what it means.
When you say

> The difference is that the array component  had an

this is not correct. IO (StorableArray Int CDouble) is a monadic
*value* itself, which represents an *action* which returns a storable
array, and since you are filling in the slot in Rmatrix with the
action (newListArray a l), this monadic value represents the action
of creating a new array whenever the action is executed.

Whereas (StorableArray Int CDouble) is the actual array itself.

You could also use your old definition of Rmatrix but change the way
it is created eg:

listtoRmatrix r c es = do
arr <- newListArray (0, r * c) es
return (Rmatrix r c (return arr))

do
r2 <-  listtoRmatrix 3 2 [1, 1, 1, 1, 1, 1]
-- the rest is old code

and everything would work as expected, because in this case, the
monadic action contained in Rmatrix just returns the array arr that
was created in the execution of  listtoRmatrix 3 2 [1, 1, 1, 1, 1,
1], because listtoRmatrix is the only place where the action of
creating a new array, ie (newListArray (0, r * c) es) is actually
executed.

I think the subtlety is one of these things that's very difficult to
understand at first, but once you've grasped the fact that in Haskell
expressions can evaluate to actions which are themselves values, and
which in turn can create new values when executed, it will hopefully
become a lot clearer.

Regards, Brian.

--
Logic empowers the living and justifies the dead.
But societal laws, and religious dogma,