[Haskell-cafe] Finally tagless - stuck with implementation of
carette at mcmaster.ca
Mon Oct 5 17:33:29 EDT 2009
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!
Günther Schmidt wrote:
> Hello Jacques,
> thanks, that is disappointing in some way, guess I still have a lot to
> Am 05.10.2009, 18:06 Uhr, schrieb Jacques Carette <carette at 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).
More information about the Haskell-Cafe