Hello, (appologies --- as I was writing, my post digressed from your original point, I hope the discussion is still interesting though :-)
On Sat, 29 Jan 2005 18:48:00 -0800, John Meacham <[EMAIL PROTECTED]> wrote: > ... > instance (Monad m, Monad (t m), MonadTrans t, MonadStats m) => MonadStats (t > m) where > mticks' n k = lift $ mticks' n k > > the first, however, is tricky. Right now, it appears that every Monad > type in the libraries defines a rule for commuting with every other > monad type, this seems impracticle for many monads (n^2 rules!) so, my > question is, why arn't the standard monad transformers declared with an > instance like above? The library defines the interaction of every transformer with every other one. If you think of monad transformers as "language features", we are simply saying how each features interacts with every other one (this is why we have to be careful when we introduce new language features :-). Not all features are orthogonal (i.e. they don't all commute). In my experience, the features that don't commute are the ones that somehow tend to affect the control flow of the program, e.g. exception handling, backtracking, explicit continuations. Now for many transformers the interaction with other ones is "straight forward" and can be captured with a declaration like the above. Such declarations lead to overlapping instances, usually you need to rules, e.g. instance ReaderM (ReaderT r m) r where ... instance (ReaderM m r, Trans t) => ReaderM (t m) r where ... The overlapping instances are nice in this case, as they cut down on the code a lot. However the interaction of overlapping instances and functional dependencies is a bit unclear (at least in my mind). This leads to the question" "Should functional dependencies be used?". I have heard arguments both for, and against using them. The question is "can a monad be a reader in more than one way?". Clearly we can make such moands (use ReaderT twice). But then, when we say "Get the environment", which one do we mean? With functional dependencies the answer (usually) is: get the outermost environment, and you have to do something special (explicit lifting) to access the other ones. Without fun.deps. the answer is: try to figure out which one we mean, based on the expected type of the value. Often that leads to ambiguities, but of course that can be fixed by writing types. Neither of the approaches is particularly satisfying: the point is that if we are going to have more than one of something, then different things should have names, so that we can specify whcih one we mean. With fun. deps. we only have a single name (the putermost one), without them, we are using the types of things for their names. Both of these are unsatisfactory. It is possible in Haskell to code up a name like system --- I wrote a library like that once, and it is on my web page (www.cse.ogi.edu/~diatchki). It involves the (by now usual) class hackery and it is not real pretty. Essentially, classes get another parameter (the name of the layer), and there is functional dependenciy between the monad and the name, but not the type, e.g. you get constraints like: ReaderM m x t saying: "the monad 'm' has a read-only field called 'x' of type 't'". Sadly you cannot pick arbitrary names for your variables, instead the variable names are natural numbers. Note that now the functional dependency makes sense --- it says that we should not have variables with the same name, but we can have multple variables of the same type. A language feature avoiding such hackery would be nice. By the way, note that having multiple layers of the same monad is really useful sometimes and the layers cannot be colapsed into a single layer with a tuple. For example: StateT s1 (ExceptT err1 (StateT s2 m)) We cannot colapse the two state layers into a single one. Raising an 'err1' error undoes the changes to state variable 's1', but not the changes to variable 's2'. > ** The monad transformer libraries appear to have moved somewhere in the > most recent cvs fptools tree, anyone know where they moved too? I am not sure where "the standard" library is. There are some transformers under: libraries/monads. They are very similar to the ones in the standard library. The ones in CVS are my working version, there is a link to a "stable" one (yeah right :-) on my web page (monadLib), and the next realease should appear there sometime this week (maybe even today). -Iavor _______________________________________________ Haskell mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell
