[Haskell] Re: Global Variables and IO initializers
koen at cs.chalmers.se
Thu Nov 4 12:28:56 EST 2004
Ben Rudiak-Gould wrote:
| I'm not convinced this is a problem either. All you have
| to do is use a single parameter (?MyModule.globals ::
| MyModule.Globals), where MyModule.Globals is an abstract
| type, and you've hidden your implementation as completely
| as if you had used unexported global variables.
Are you suggesting to always add the context
(?MyModule.globals :: MyModule.Globals) to every function in
every module you implement? (My example concerned a module
that was previously implemented without global variables,
and now was going to be implemented with global variables.)
| [...] The original implicit-parameter paper suggested an
| extension of Haskell to support partial constraints in
| type signatures, e.g.
| pretty :: ... => Doc -> String
| with the unspecified constraint being filled in by the
| type inferencer (section 5.4).
(Ah! I had forgotten about that. See also:
| I think the OP is proposing the same thing, except
| without the ellipsis: i.e. we just write
| pretty :: Doc -> String
| and the compiler infers pretty :: (?width :: Int) => Doc
| -> String, or whatever. This actually sounds like a very
| good idea to me.
I think hiding the fact that certain objects are not
constants but functions is a bad idea, because it will break
sharing in a lazy implementation.
| Adrian Hey proposed a "SafeIO" monad with similar
| properties to yours. I have the same objection to both of
| them: a whole new monad and a bunch of interconversion
| functions seems like overkill for such a minor new
| language feature.
I was not aware of his proposal. I don't think it is that
* 1 new monad
* for each current safe IO operation, 1 new operation
(read: newIORef. What else?)
* possibly, a function convertCIOtoIO :: CIO a -> IO a
(* part of compilers: a function unsafeIOtoCIO :: IO a -> CIO a)
| And I have the same counter-proposal: why not use (forall
| s. ST s)? It's not commutative, but I think it has all of
| the properties we need.
Interesting idea. However, when I then provide a function
for creating an IORef (which is what this extension would be
used for mostly), I get this:
newIORefST :: a -> ST s (IORef a)
Which is probably not what you want.
| So importing a module doesn't have side effects, and init
| actions can be implemented easily using unsafePerformIO
| without affecting the semantics.
I don't understand this remark.
| Note that the ST monad does not require higher-order
| polymorphism -- only the runST function requires that. ST
| is still useful without runST, as this example
So, if I get it right, you want to use (forall s . ST s)
because it avoids adding yet another monad to Haskell?
More information about the Haskell