Tony Morris writes:
 > Yes, but where does the IORef live? Wouldn't I have to pass it back and
 > forth between invocations? If not, where do I get the IORef from on
 > subsequent invocations? Got a short example?

That's where the unsafePerformIO comes in. With unsafePerformIO and IORefs, you
can have global mutable variables:

{-# NOINLINE #-}
memo :: IORef Int
memo = unsafePerformIO (newIORef Nothing)

f = unsafePerformIO $ do
  ref <- readIORef memo
  case ref of
    Just val -> return val
    Nothing  -> let val = complexCalculation
                in writeIORef memo val >> return val

Something like that. If f took an argument then you'd probably use a IORef Map
or IORef IntMap or something in place of IORef Int. Be careful to:

1) Not break referential transparency. I.e. in my example, f will always return
the same value, how ever many times you call it. It's possible to break this
property using this trick.

2) Not use polymorphic references, as they lead to type unsafety [1].

3) Always use the {-# NOINLINE #-} pragma on any IORefs you create this way.

[1]: 
http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html#v%3AunsafePerformIO

--
-David House, [EMAIL PROTECTED]
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to