[Haskell-cafe] Memo + IORef
David House
dmhouse at gmail.com
Sat Jun 16 08:27:07 EDT 2007
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, dmhouse at gmail.com
More information about the Haskell-Cafe
mailing list