monad-embed-to-Haskell conversion

This page describes how types and expressions in monad-embed are compiled into Haskell.

Converting types

In monad-embed Converted to Haskell
x :: {m} a
x :: m a
f a
f a
(a -> {m} b)
(a -> m b)
([{m} a] -> {n} b)
(m a -> n b)
(t / m)
ComposeMonad t m
where
data ComposeMonad t m a =
    ComposeMonad (m (t m a))

Converting expressions

In monad-embed Converted to Haskell
(\ arg -> body)
return $ \a -> let
    arg = return a
    in body
arg has a polymorphic flavor.
(function arg)
function >>= \f ->
    (arg >>= \a ->
    (f a))
\ [arg] -> body
return (\arg -> body)
(function [arg])
function >>= \f ->
    (f arg)
1234567
return 1234567
case subj of {
    Con field -> value;
    }
where
data T = {
    Con U;
    };
subj >>= \s -> case s of
    Con f -> let
        field = return f
        in value
field has a polymorphic flavor.
case subj of {
    Con [field] -> value;
    }
where
data T = {
    Con [{M} U];
    };
subj >>= \s -> case s of
    Con field -> value
do {
    var = value;
    } then rest
value >>= \v -> let
    var = return v
    in rest
var has a polymorphic flavor.
do {
    var =[] value;
    } then rest
let var = value in rest
var is monomorphic.
do {
    thing;
    } then rest
thing >>= \_ -> rest
wrap [thing]
ComposeMonad thing
ComposeMonad is as defined above.
unwrap [thing]
case thing of
    ComposeMonad x -> x
ComposeMonad is as defined above.

do-blocks with more than one binding or statement in them in them are desugared before being converted to Haskell:

do {
    first thing;
    } then do {
        second thing;
        } then (...)

The compiler back-end currently does not support pattern matching on lazy fields:

case foo of {
    ZCons a [ZCons b [ZNil]] -> ...;
    }
The desired behavior is that any monadic actions contained in the field are evaluated when the pattern is matched, much as a Haskell field containing produces only when it is matched against. However, this is a pain to convert into Haskell, so there is no support for it at the moment.