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: [EMAIL PROTECTED]>  
see: <http://www.catmint.de/elke>

for pgp public key see:
<http://www.catmint.de/elke/pgp_signature.html>

Gui.hs

STM.hs

MonadT.hs

Main.hs

Io.hs

Db.hs

Reply via email to