Hi, You can do things like that for "new" monads that are isomorphic to existing ones. Take a look at the MonadLib.Derive package from MonadLib (http://hackage.haskell.org/packages/archive/monadLib/3.5.2/doc/html/MonadLib-Derive.html). More specifically, the functions "derive_return" and "derive_bind" might be of interest. A more general property for monad transformers is that you can always define the "return" of the new monad in terms of the "return" of the underlying monad and "lift":
return_new x = lift (return x) This works because, in general, "lift" should be a "monad morphism". Hope that this helps, Iavor On Thu, Apr 9, 2009 at 3:40 AM, Bas van Dijk <v.dijk....@gmail.com> wrote: > Hello, > > Suppose you have defined a monad transformer such as: > >> newtype T1 m a = T1 { unT1 :: A1 m a } > > Where 'A1 m' is an arbitrary monad of your choosing. > For this discussion we just take the identity: > >> type A1 m a = m a -- (can be any monad) > > If you want to define a Monad instance for 'T1 m' you generally do this: > > instance Monad m => Monad (T1 m) where > return = T1 . return > m >>= f = T1 $ unT1 m >>= unT1 . f > > (I know I can use the 'GeneralizedNewtypeDeriving' language extension > to automatically derive a Monad but suppose that isn't available) > > Now when I define a new monad transformer: > >> newtype T2 m a = T2 { unT2 :: A2 m a } > > Where 'A2 m' is again an arbitrary monad of your choosing but for now > just the identity: > >> type A2 m a = m a -- (can be any monad) > > The Monad instance for it is almost completely identical to the former: > > instance Monad m => Monad (T2 m) where > return = T2 . return > m >>= f = T2 $ unT2 m >>= unT2 . f > > Note that the only differences are: > > * a function to convert > from the outer monad _to_ the inner monad: > 'unT1' and 'unT2' > > * a function to convert > _from_ the inner monad to the outer monad: > 'T1' and 'T2' > > The common parts seem to be: > > liftReturn from = from . return > liftBind from to m f = from $ to m >>= to . f > > My question is: can these be given suitable and general enough types > so that they can be used to define Monad instances for monad > transformers? > > In other words can I use them to write: > > instance Monad m => Monad (T1 m) where > return = liftReturn T1 > (>>=) = liftBind T1 unT1 > > and: > > instance Monad m => Monad (T2 m) where > return = liftReturn T2 > (>>=) = liftBind T2 unT2 > > Thanks, > > Bas > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe