I wrote: > It should be possible to implicitly return values which are not instances > of Monoid: the compiler errors out if it ever needs to merge such a type. > Wouldn't this provide a form of uniqueness typing a la Clean? In fact, > couldn't we implement safe state threads on top of this, instead of the ST > monad? In fact, couldn't we work within several state threads at once?
I think the answer is yes: I think this idea can replace the IO, ST and State monads and provide a much finer-grained form of ordering, and easy mixing. We add a new sequencing construct to Haskell, along the lines of do and proc. I'll call it "thread", though this is probably a poor choice. It takes a list of expressions and causes the implicit return values of each expression except the last one to be passed as implicit parameters to the next expression in the list. Implicit parameters not "consumed" by a particular expression would have to become implicit return values, and I'm not sure exactly how this should work. The main function has a type like (?io :: State) => ((), ^io :: State) The state parameter must be unforgeable. The simplest way to achieve this is to give it a special name which the program is forbidden to mention in binding and pattern-matching constructs. Of course this threading carries no runtime cost, as the code generator knows not to generate code to pass values of type State around. Each time the user creates a ref (or mutable array), it gets its own independent state parameter, which is automatically threaded through future uses of the ref by "thread" constructs. Any function that uses certain refs will include in its type an explicit list of the associated state parameters of those refs. This creates a problem: if each ref has its own state parameter, what are their names? This issue came up with implicit parameters also: the fact that implicit parameters have only names, whereas typeclasses are parameterized by type, was a source of surprising differences between the two. I see now that this can be solved by allowing implicit parameters and return values to be parameterized by types as well. Thus we have newRef :: a -> (exists s . Ref s a, ^st s :: State) readRef :: (?st s :: State) => Ref s a -> (a, ^st s :: State) writeRef :: (?st s :: State) => Ref s a -> a -> ((), ^st s :: State) (It's not clear that readRef actually needs to return the state.) Furthermore, there should be a subclassing system for implicit values, so that (for example) the IO monad can be split into independent pieces and ?io can be shorthand for all of them. -- Ben _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell