And just because this has not been explicitly stated: it's not just
for aesthetic reasons that you couldn't do this with a pure function,
but because it violates the semantics and gets you the wrong result.
So for example, if you modified Tim's code to be
import Data.IORef
import System.IO.Unsafe
mkNext :: (Num a) => IO a
mkNext = do
ref <- newIORef 0
return . unsafePerformIO $
do
modifyIORef ref (+1)
readIORef ref
main :: IO ()
main = do
foo <- mkNext
print foo
print foo
print foo
Then the output that you will see (with GHC at least) is
1
1
1
because the compiler assumes that it only needs to evaluate foo once,
after which it can cache the result due to assumed referential
transparency.
- Greg
On Oct 21, 2009, at 11:40 AM, Tim Wawrzynczak wrote:
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...
Cheers,
Tim
On Wed, Oct 21, 2009 at 1:30 PM, minh thu <not...@gmail.com> wrote:
2009/10/21 Tim Wawrzynczak <inforichl...@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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe