[Haskell-cafe] Simple but interesting (for me) problem

minh thu noteed at gmail.com
Wed Oct 21 15:08:50 EDT 2009


2009/10/21 Tim Wawrzynczak <inforichland at gmail.com>:
> 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 <noteed at gmail.com> wrote:
>>
>> 2009/10/21 Tim Wawrzynczak <inforichland at gmail.com>
>> >
>> > 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
>
>


More information about the Haskell-Cafe mailing list