
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... -- -David House, dmhouse@gmail.com