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: http://www.mail-archive.com/[EMAIL PROTECTED]/msg05186.html :-) | 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 bad: * 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) That's it! | 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 | demonstrates. So, if I get it right, you want to use (forall s . ST s) because it avoids adding yet another monad to Haskell? Regards, /Koen _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell