
BTW, here is a more symmetric version of the same code:
lam f = I . return $ unsafePerformIO . unI . f . I . return
which has a very clear pattern of
lam f = embed $ extract . f. embed
where 'embed' is often called "return". Implementations of lam in
"tagless final" style tend to follow the above pattern of embed/extract,
each specialized to the particular repr implementation.
In some cases, one only needs a "context-sensitive" extract, i.e. an
extract which is only valid in the context of an outer 'embed'. The
most important example is code-generation in metaocaml where the
'compiler' version of lam reads
let lam f = .
Hello Jacques,
thanks, that is disappointing in some way, guess I still have a lot to learn.
Günther
Am 05.10.2009, 18:06 Uhr, schrieb Jacques Carette
: It's possible, but it's not nice. You need to be able to "get out of the monad" to make the types match, i.e. lam f = I (return $ \x -> let y = I (return x) in unsafePerformIO $ unI (f y))
The use of IO 'forces' lam to transform its effectful input into an even more effectful result. Actually, same goes for any monad used inside a 'repr'.
let_ and fix follow a similar pattern (although you can hide that somewhat by re-using lam if you wish).
Jacques