Dear friends -
I must have clicked "reply" instead of "reply all" so here is the reply haskell cafe would have received:

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
component  had an
additional monad wrapper around and now it doesn't.  That is,

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
additional monad wrapper around and now it doesn't.

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,
empower the dead,
to destroy what's living.

http://www.metamilk.com
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to