
2009/10/21 Tim Wawrzynczak
True...here we go then:
import Data.IORef import System.IO.Unsafe
mkNext :: (Num a) => IO (IO a) mkNext = do ref <- newIORef 0 return (do modifyIORef ref (+1) readIORef ref)
next :: IO () next = do foo <- mkNext a <- sequence [foo,foo,foo] putStrLn $ show a
running next will print [1,2,3] which is the result of calling 'foo' 3 times.
But technically then, mkNext is just an IO action which returns an IO action ;) and not a function which will return the next value each time it is called, hence the need to extract the value from mkNext, then use it...
That why it is called mkNext: do next <- mkNext sequence [next, next, next]
Cheers, Tim
On Wed, Oct 21, 2009 at 1:30 PM, minh thu
wrote: 2009/10/21 Tim Wawrzynczak
Here's an example in the IO monad:
import Data.IORef import System.IO.Unsafe
counter = unsafePerformIO $ newIORef 0
next = do modifyIORef counter (+1) readIORef counter
Naturally, this uses unsafePerformIO, which as you know, is not kosher...
But you don't close around the Ref like in your schemy example.
mkNext = do ref <- newIORef 0 return (do modifyIORef ref succ readIORef ref)
mimic your other code better.
Cheers, Thu