[Haskell-cafe] Linking to third party libraries in windows

Matthew Bromberg mattcbro at earthlink.net
Sat May 27 12:33:28 EDT 2006

That's an interesting statement that bears further scrutiny.  I've been 
viewing monads as a kind of encapsulation in a quasi-hidden world state. 
Yes a monad is a function that would give you an output if you had 
access to the input world.  That is the picture drawn in Simon Peyton 
Jones' tutorial.  I've been thinking of actions in terms of the 
functions x -> IO(a), but Simon calls these IO actions and calls monads 
actions as you do.

Is it your claim that whenever an 'IO action' is performed on something 
like  IO (x)  with x <- newListArray a l
that the newListArray function will be called ?  So with the old 
paradigm, where Rmatrix was stored as
(Int, Int, IO(StorableArry Int CDouble)).  A typical matrix operation, 
that calls out to a BLAS C routine cside_effect()  looks something like 
this under the old scheme

matfunc A = (u,v, arr) where
     u = f1  (getrows A)  (getcols B)
     v = f2  (getrows A)  (getcols B)
    arr = do
       arrA <- getarr A
       withStorableArray arrA  (\vara -> cside_effect vara )
       return arrA

Now when one uses this code
    A <- getAfromSomewhere
   fA = matfunc A
   B <- anotherfunc A

fA has been changed by the cside_effect function, but A has not!  Is it 
your contention that the array in A is essentially copied or created 
anew for every getarr A call?  I think getarr A looked something like

getarr (Rmatrix (r,c,arr)) =  arr

in the old technique, but now looks like

getarr (Rmatrix (r,c,arr)) =  return arr

Is this perhaps an effect of lazy evaluation?  When does one actually 
need to evaluate the constructor for the storable array contained in A? 
Hmmm. Is it that the rules specify that an IO action forces the 
evaluation of the value in the monad, but otherwise this value may be 
unevaluated?  So    return x  doesn't evaluate x but     (return x)  
 >>=   \z -> IOfunc z  does?

This would actually make sense in the end.  The IO action of
A <- getAfromSomewhere would not evaluate the monad that is the third 
element of the tuple A, since there is no real 'need' to do so.  So in 
fact no constructor of A's array would ever get evaluated until a 
function was applied to it, which would have to be in the form of an IO 
action.  That's a nice mind twister.  Clean's uniqueness types are a 
little easier to grasp I think.  Ahh I think I understand now.  It has 
to work that way or else you cannot guarantee the sequential execution 
property of monads.  Thus if  y :: IO (a) and you evaluate
   z <- func (f1 y) (f2 y),  the evaluation order of y is controlled by 
what is implemented in func (and f1 and f2),  not by evaluation rules 
for arguments. The value wrapped in y MUST remain unevaluated until IO  
'actions' are performed on it.

Brian Hulley wrote:

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.

More information about the Haskell-Cafe mailing list