[Haskell] IORef sharing

Rodney D Price rodprice at raytheon.com
Mon Oct 27 20:25:28 EDT 2008

Thanks for all the replies.

Perhaps my mental picture is a little less flawed,
now, but this brings up something about the IO
monad that has always bothered me.  Papers on the
IO monad say things like "A term of type IO ()
denotes an action, but does not necessarily perform
the action." (Wadler, "How to Declare an Imperative")
Or, "putc '!' denotes the command that, if it is ever
performed, will print an exclamation mark."

Okay... However, when I use IO in a Haskell program,
the response is usually pretty snappy.  It's not as
if the Haskell runtime is hanging around, waiting for
some time in the future when it might be appropriate
to do IO.  It happens right now.  Yet the literature
gives the impression that the IO monad in particular
is a clever trick to preserve referential transparency
by gathering up all the IO actions, but not necessarily
actually *performing* them.  Then the Haskell runtime
holds its nose and *performs* them when necessary.

But at least a couple responses to my question have
said that the IO action is performed when `<-` (or
equivalently, bind, >>=) is executed.  My head has a
hard time holding a mental model of code in which IO
might happen at some unspecified time in the future.
A mental model in which IO happens when >>= is
executed is a lot better fit for my head.

Yet, I remain a bit nervous about this new (to me)
mental model.  Is this just an intuition that works
99.9% of the time, or is it actual, literal fact?


On Oct 27, 2008, at 5:43 PM, Timothy Goddard wrote:

> On Tue, 28 Oct 2008 12:02:54 Rodney D Price wrote:
>> My old, deeply flawed mental picture had "iio" taking
>> the role of a pointer to a value.  My bright, shiny
>> new mental picture has "iio" acting just like a C
>> #define macro: every time I call "iio", I'm really
>> just writing "newIORef 0".  Is that what you're saying?
>> -Rod
> No, this isn't the behaviour of IORefs at all - you're getting mixed  
> up with
> Haskell's syntax. <- in a do block means perform the contained  
> action and let
> me use the result. = defines a term and is effectively just an alias  
> - it
> doesn't run anything by itself.
>> iio :: IO (IORef Int)
> This means "iio is an IO operation which produces an IORef to an Int"
>> iio = newIORef 0
> This means "iio is creating a new counter starting at 0"
>> ic1 = do { io <- iio ; count io 0 }
> This is an IO operation which runs iio, creating a new IORef in the  
> process,
> and then starts a counter at 0 and returns it.
>> ic2 = do { io <- iio ; count io 0 }
> This runs iio again, creating another IORef, and then starts a  
> counter on the
> new IORef.
> Haskell doesn't have mutable global variables - it goes against the  
> grain of a
> pure language. You have to create the IORef within an IO procedure  
> and pass
> it in. You really should write:
> counter = do
>  io <- newIORef 0
>   c1 <- count io 0
>   c2 <- count io 0
>   c1 'a' >>= print
>   c2 'b' >>= print
>   c2 'a' >>= print
>   c1 'a' >>= print
> This should behave as you expected - it creates the IORef then  
> creates two
> counters sharing it.
> Remember that when you return IO a, you're returning an IO operation  
> that
> produces an a. That operation is not run until it is bound to the  
> main IO
> monad. Haskell's IO looks like any other language if you're only  
> writing and
> calling procedures normally but as soon as you start passing around
> references to IO procedures you need to understand a little more  
> about how
> monads work.
> In the real world using IO counters is probably something to avoid.  
> Only the
> part of your program that is actually interacting with the outside  
> world
> should use IO at all, and keeping an internal count doesn't need this.
> Minimise IO and Haskell will reward you. Let IO spread all through  
> your
> program and it will be no safer than the C the developer was really  
> thinking
> in.
> Cheers,
> Tim
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell

More information about the Haskell mailing list