[Haskell-cafe] Top-level state debate on the wiki
jules at jellybean.co.uk
Wed Dec 1 16:00:55 EST 2004
On 1 Dec 2004, at 18:29, Ben Rudiak-Gould wrote:
> Here's the page:
What I think is missing is an explanation of when you would want this
feature (and when you wouldn't, more importantly). Here is the kind of
platonic dialogue that summarises my limited understanding:
A: I want a global variable x which IO actions f and g can alter. Why
can't I say x <- newIORef 0::Int at the top level?
B: Why would you? Put the newIORef command at the beginning of your
main action and pass the reference to f and g. This is much better
programming practice: you can invoke f and g again on different
references whenever you want to, useful for debugging and testing.
A: Ah, but this isn't scaleable, is it? What if I have y and z and q
and r and..... I really don't want f and g to have *that* many
B: That's easy, just wrap them up in a single type. Call it GEnv, if
you like, for Global Environment. Now all your IO actions just need one
A: But the bodies of f and g call many other actions, most of which
need access to some part of this environment. It's a real pain
threading the global environment parameter to all of these actions! It
would be so much simpler to just make them top-level globals!
B: Problem threading parameters? Sounds to me like you want a state
monad. You know you can use StateT GEnv IO to layer that over IO,
right? In fact, in many programs you will not even need IORefs any
more, since the StateT gives you modifiability for free.
[A wanders off muttering...]
[...some time later...]
A: Ah! I've got you now! I'm implementing a module which exports a Map
interface. It's a pure interface, no IO monads in sight. But, I want to
implement it with constant-time lookup, so I need a hashing algorithm
and a mutable hashtable, right?
B: No problem, you should be using the ST monad and STUArray, probably.
....which is to say, that I don't have a very clear idea of when you do
need it, although I think I have some ideas of when you don't need it.
The example that I haven't addressed is the 'OS-in-haskell' family of
examples, which I don't understand clearly enough to summarise.
More information about the Haskell-Cafe