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 = .<fun x -> .~(f .<x>.)>.
where the .~ does an extract -- but *only* in the context of a surrounding code bracket (i.e. .< >. ). If there is such a context-sensitive "extract" for the IO monad, i.e. something which allows you to pretend you've got a result in IO only valid *inside* IO, then you can use that to write a nicer lam. I tried all the obvious things with monadic operators to get this done, but did not succeed in the time I had. Maybe Oleg or Ken can. So don't give up hope quite yet!

Jacques

Günther Schmidt wrote:
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 <care...@mcmaster.ca>:

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

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to