sam lee | 12 May 15:49

M1 + M2 = M3 where both computations in M1 and M2 can be used?

Hi.

I want to compose two monads to build another monad where
computations of the two monads can be used inside.

I have:

- MonadTypeInfer : interface (class) for TypeInfer monad
- TypeInfer : a monad that has Map String Type (association of names and types)
- TypeInferT : transformer of above monad
- MonadEval : interface (class) for Eval monad
- Eval : a monad that has Map String Expr (association of names and
code/function body)
- EvalT : transformer of Eval
- tInfer :: Expr -> TypeInfer Type -- given expr, returns type of it
in TypeInfer monad
- eval :: Expr -> Eval Expr -- given expr, returns normalized expr in Eval monad

Problem: in repl, when user defines a function, it should type check
and register type of the function to TypeInfer monad's Map String
Type.
Also, it should store the expression of the function in Eval monad.

I build REPL monad using TypeInferT and EvalT.

> newtype REPL a = REPL { runREPL :: TypeInferT (EvalT IO) a }
>   deriving(Monad, Functor, MonadIO, MonadTypeInfer, MonadEval)
> repl :: REPL ()
> repl = do
>   input <- prompt ">>> "
(Continue reading)

Twan van Laarhoven | 12 May 16:38

Re: M1 + M2 = M3 where both computations in M1 and M2 can be used?

sam lee wrote:

> Hi.
> 
> I want to compose two monads to build another monad where
> computations of the two monads can be used inside.
> 
> I have:
> 
> - MonadTypeInfer : interface (class) for TypeInfer monad
> - TypeInfer : a monad that has Map String Type (association of names and types)
> - TypeInferT : transformer of above monad
> - MonadEval : interface (class) for Eval monad
> - Eval : a monad that has Map String Expr (association of names and
> code/function body)
> - EvalT : transformer of Eval
> - tInfer :: Expr -> TypeInfer Type -- given expr, returns type of it
> in TypeInfer monad
> - eval :: Expr -> Eval Expr -- given expr, returns normalized expr in Eval monad
> 
> Is there a way to build a monad where you could use sub-monads'
> (monads used to build current monad) computations?

A solution to this problem is to use type classes, and in particular MonadTrans. 
You can then give an instance of MonadTypeInfer for EvalT m where m is an 
instance of MonadTypeInfer, and similarly an instance MonadEval for TypeInferT 
m. How this is implemented depends on the Monads in question, but if you use the 
monad transformer library with newtype deriving you can just add "deriving 
MonadTrans".

(Continue reading)

sam lee | 13 May 00:22

Re: M1 + M2 = M3 where both computations in M1 and M2 can be used?

 > tInfer :: MonadTypeInfer m => Expr -> m Type
 > eval   :: MonadEval      m => Expr -> m Expr

That solves!
I should've left out type annotation.

On Mon, May 12, 2008 at 10:38 AM, Twan van Laarhoven <twanvl <at> gmail.com> wrote:
> sam lee wrote:
>
>
> >
> > Hi.
> >
> > I want to compose two monads to build another monad where
> > computations of the two monads can be used inside.
> >
> > I have:
> >
> > - MonadTypeInfer : interface (class) for TypeInfer monad
> > - TypeInfer : a monad that has Map String Type (association of names and
> types)
> > - TypeInferT : transformer of above monad
> > - MonadEval : interface (class) for Eval monad
> > - Eval : a monad that has Map String Expr (association of names and
> > code/function body)
> > - EvalT : transformer of Eval
> > - tInfer :: Expr -> TypeInfer Type -- given expr, returns type of it
> > in TypeInfer monad
> > - eval :: Expr -> Eval Expr -- given expr, returns normalized expr in Eval
> monad
(Continue reading)

Kenn Knowles | 12 May 20:33

Re: M1 + M2 = M3 where both computations in M1 and M2 can be used?

On Mon, May 12, 2008 at 6:51 AM, sam lee <skynare <at> gmail.com> wrote:
> Hi.
>
>  I want to compose two monads to build another monad where
>  computations of the two monads can be used inside.

Twan's suggestion seems like a natural way to continue with the
existing code you have described (based on monad transformers).  If
you would like to understand this issue in some depth, I recommend the
following paper which presents a general way to combine two monads
that is not biased towards having one "contained" in the other.

 - Composing monads using coproducts. C L=FCth, N Ghani. ICFP 2002.
 - http://www.mcs.le.ac.uk/~ng13/papers/icfp02.ps.gz

I just tried it out the other day, so if you'll excuse the
self-promotion here is a demonstration

http://www.kennknowles.com/blog/2008/05/10/debugging-with-open-recursion-mixins/

- Kenn

Gmane