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