
On 07/01/14 03:21, Brandon Allbery wrote:
On Mon, Jan 6, 2014 at 10:15 PM, Courtney Robinson
mailto:courtney@crlog.info> wrote: On Tue, Jan 7, 2014 at 3:03 AM, Brandon Allbery
mailto:allbery.b@gmail.com> wrote: behind
Oh I see, thanks for the info. really helpful. It brings about another question now.
How is newIORef meant to be used so that I only have a single IORef?
The Haskell way is to carry such things implicitly in a State or Reader monad; since the IORef itself doesn't change, and you need the IO monad around anyway to actually use it, you would use a ReaderT IORef IO and then use ask >>= liftIO . readIORef to get the value and similar to write or modify it. (Commonly one uses a type or newtype+newtype deriving to make one's own monad combining them.)
You don't have to go that far though, if you want a 'global' IORef then you simply make it at the top of your program and then pass it around to anyone who needs access it to: main :: IO () main = do counter <- newIORef 0 doThingsWithCounter counter doThingsWithCounter :: IORef Int -> IO () doThingsWithCounter counter = |atomicModifyIORef counter $\x -> lety =x +1in(y,y) |So this gives you a way to have global variables, but without the pain that they can bring in other languages. The Reader monad stuff that Brandon suggests is a way to implicitly have this IORef passed around everywhere, which can be useful if you have deeply nested calls where only the children really need access to the IORef - it saves you having to add a new parameter everywhere. - ocharles ||