[Haskell-cafe] Re: Sequencing Operations in a Monad

apfelmus apfelmus at quantentunnel.de
Sat Sep 15 04:07:26 EDT 2007


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



More information about the Haskell-Cafe mailing list