monad transformer library (was: in list transformer)

Iavor Diatchki
Wed, 04 Jun 2003 11:38:16 -0700


comments cool!  i didn't think anyone would look at the library :-)

Ross Paterson wrote:
> A few comments on your recent commit of a proposed new monad structure
> (fptools/libraries/base/Control.Monad.X.*):
> I never liked the old "diagonal" structure, but a lot of people use
> these modules, and they'll notice the change of interface.
well, in the old library there didn't seem to be a particular structure
(perhaps this is what you mean by diagonal).  for example:
  * the instance that StateT is a writer (if underlying monad is a 
writer) is in State.hs
  * the instance that ReaderT is a writer (if underlying monad is a 
writer) is in Writer.hs

i tried to make the new library mostly compatable with the old one,
but i think it is good to fix up things before the library has 
completeley solidified.

> In the old scheme, Control.Monad.Fix was portable, and now it isn't.
> (This will ripple through to my favourite module, Control.Arrow.)
> I'd prefer that the MonadFix instances for the new monad transformers
> be defined in the transformer modules, so they could import a portable
> Fix as before.
i have mixed feelings about MonadFix. on the one hand i quite agree with 
you that the instances kind of belong with the transformers.  on the 
other i've had discussions with some collegues of mine, that think that 
since using monadic recursion is not that common, you should only get 
those instances when you use it, i.e. import Fix.  this motivated 
separating them.  but the potability issue you bring up is quite 
relevant (although one gets the portability at the cost of having very 
few instances).   overall i agree with ross that they should probably be 
moved back to the transformers.  any other opinions?

> You defined the classes in Trans, the types in Types and the instances
> in the *T modules, which makes them orphan instances, I believe (cf GHC
> User's Guide 4.9.8).  Why not just get rid of Types and move the type
> definitions into the relevant *T modules?
Types (and Utils) were supposed to be "private" modules.  Types is used 
to access the underlying representations of the transformers, while the 
*T files still export the types abstractly.  moving the mfix instance to 
the transformers will remove the need for Types, so perhaps that should 
be done.

> Use of type synonyms, like
> 	type Reader r = R.ReaderT r Identity
> is more economical, but will lead to more complex error messages.
this is a good point and i will change that, unless anyone objects?

> Resumptions may be generalized to
> 	newtype ResumeT f m a   = Re { unRe :: m (Res f m a) }
> 	data Res f m a          = Value a | Delay (f (ResumeT f m a))
> where f is a functor.

interesting, i hadn't seen that. this will also make the Resume monad a 
little more interesting
(it used to be kind of like the natural numbers).  i'll add that.  is 
there a paper where they discuss that?  i also haven't really proved the 
monad laws, hopefully they still work.

thanks for the comments