Does someone like to comment on this? I'm planning a new cli/odbc-based database connectivity library for Haskell 98 and want to manage hidden state (various management information) on the Haskell side. Some libs. i.e. for gui, extend the IO monad for this using some "start" function: main :: IO () main = start prog prog :: GUI () ... I could do the same with my library, but then it is difficult to combine, for example, Gui operations with Db operations. I found a better solution in Jeuring/Meijer 1995 in Mark P. Jones' contribution which consists of using monad transformers and lifting monad operations to class level like this: type M a = DB (GUI IO) a startM = start . start main = startM prog prog :: (Io m, Gui m, Db m) => m () prog = ... I hope that this approach not only solves the problem mentioned above but also supports a more modular approach to handling state etc. in general and encourages the programmer to add his own monads (instead of packing all into IO or passing around state etc. explicitly). However, to be really useful, it would be best if there could be established a "standard framework" for such libraries. It would be nice if there were at least agreement on how to lift IO operations to class level: 'Io.putStr' (which provokes name clashes with the standard prelude),'Io.putStrC' (C for class level), or some other prefix/suffix. In addition to Mark P. Jones' examples in the mentioned article, - Class Io must be provided, - all specific monad operations should be encapsulated in ADTs, - it must be possible to map 'lift' into the ADT In the attachements I have worked out a scenario, where DB and GUI are state monad transformers and Io and Gui are defined as follows: class Monad m => Io m where io :: IO a -> m a class Monad m => Db m where db :: DBImpl m a DBImpl is an ADT which encapsulates a set of characteristic monad operations, in this case the 'modify' operation of a state transformer. For such ADTs, a special class Liftable l where mapLift :: (MonadT t, Monad m) => l m -> l (t m) has been introduced to supply a unified symbol for applying lift to the encapsulated monad transformation(s). (I don't like the class name either but didn't find a better up to now...) However, there remains a problem with the type system. Ideally, it would be possible to require: class (Monad m, Monad (t m)) => MonadT t where lift = ... such that MonadT applications become automatically members of class Monad, and declare instance (Db m, MonadT t) => Db (t m) where db = mapLift db (same for class Gui etc.) with the obvious effects. Both seems to be not even possible in the extended type systems of Hugs and ghc. I want to create a library for Haskell 98, so this is of minor importance, but if there was a way to make life easier for those who use type system extensions without complicating the situation for Haskell 98 users, I would of course prefer such a solution. Until then, again, I think that "standard framework" would make it easier for users to create those instance declarations by themselves needed to combine monad transformers from different sources. Elke. --- "If you have nothing to say, don't do it here..." Elke Kasimir Skalitzer Str. 79 10997 Berlin (Germany) fon: +49 (030) 612 852 16 mail: elke.kasimir@catmint.de> see: <http://www.catmint.de/elke> for pgp public key see: <http://www.catmint.de/elke/pgp_signature.html>