[Haskell-cafe] Sequencing Operations in a Monad

SevenThunders mattcbro at earthlink.net
Sat Sep 15 13:50:33 EDT 2007




apfelmus wrote:
> 
> SevenThunders wrote:
>> Ryan Ingram wrote:
>>> As long as the FFI calls don't make destructive updates to existing
>>> matrices, you can do what you want.
>>>
>>> For example, assuming you have:
>>>
>>> -- adds the second matrix to the first & overwrites the first
>>> matrixAddIO :: MatrixIO -> MatrixIO -> IO ()
>>>
>>> -- creates a new copy of a matrix
>>> matrixCopyIO :: MatrixIO -> IO MatrixIO
>>> ...
>>>
>>>
>> Well as you point out there is an efficiency issue if we need to copy
>> matrices all of the time in order to insure 'referential transparency'.  
>> Moreover I manage my matrices on a stack  in C, since it makes it easy to
>> handle memory allocation and deallocation.  The stack configuration tends
>> to
>> be highly fluid so there are always side effects going on.  Right now my
>> Matrix type wraps the index from the bottom of the Matrix stack into the
>> IO
>> monad.
> 
> If you need destructive updates, you indeed need a monad. Otherwise, I'd 
> use ForeignPtrs and import the matrix operations as pure functions (~ 
> unsafePerformIO).
> 
>>  I was just wondering if there was any obvious way to force an IO action
>> to
>> execute only once, since now each reference to the action IO causes it to
>> execute again.
> 
> Isn't that simply
> 
>    do
>      x <- onlyOnce
>      mult x x
> 
> with
> 
>    onlyOnce :: IO Int
>    mult :: Int -> Int -> IO Int
> 
> ?
> 
> If you want
> 
>    mult = liftM2 something :: IO Int -> IO Int -> IO Int
> 
> you can
> 
>    do
>      x' <- onlyOnce
>      let x = return x'
>      mult x x
> 
> which is
> 
>    do
>      x <- return `liftM` onlyOnce
>      mult x x
> 
> for short.
> 
> Regards,
> apfelmus
> 
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 
> 

I think  you are right. This is about my only choice.  All 'computations'
must first occur inside the monad.  
For a binary operation that kind of implies a type signature of the form,

-- matrix multiplication, integer indices into Matrix stack
(*.)  ::  Int -> Int -> IO (Int)
-- addition
(+.)  :: Int -> Int -> IO (Int)


But what if I want to do something like    a *. ( c +. d)  ?  Well I'll have
to live with

do
   s <- c +. d
   p <- a *. s

Unless I additionally define an multio  multiplication operator
(multio)  ::  Int ->  IO(Int) -> IO(int)

so that I can do
do
   s <- a `multio` (c +. d)
-- 
View this message in context: http://www.nabble.com/Sequencing-Operations-in-a-Monad-tf4446047.html#a12692293
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.



More information about the Haskell-Cafe mailing list