Re: Functional dependencies and type inference (2)
Louis-Julien Guillemette wrote:
Say we are using a GADT to represent a simple language of boolean constants and conditionals,
data Term a where B :: Bool -> Term Bool Cnd :: Term Bool -> Term t -> Term t -> Term t
and we would like to perform a type-safe CPS conversion over this language. We encode the relationship between the types in the source language and those in the CPS-converted language using a class and a fundep:
Here's the code that seems to do what you wished. Liberty is taken to extend the language so we can CPS convert more interesting terms. Here are the tests
term1 = Cnd (Cnd (B True) (B False) (B False)) (B True) (B False) test1 = shw (cps term1 id) ""
*CPS> test1 "Cnd (B True)(Cnd (B False)(B True)(B False))(Cnd (B False)(B True)(B False))"
term2 = Cnd (Cmp (Cnd (B True) (I 1) (I 2)) (I 3)) (B True) (Cmp (B True) (B False)) test2 = shw (cps term2 id) ""
*CPS> test2 "Cnd (B True)(Cnd (Cmp (I 1)(I 3))(B True)(Cmp (B True)(B False))) (Cnd (Cmp (I 2)(I 3))(B True)(Cmp (B True)(B False)))" The code: {-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} module CPS where data Term a where B :: Bool -> Term Bool Cnd :: Term Bool -> Term t -> Term t -> Term t I :: Int -> Term Int Cmp :: Term t -> Term t -> Term Bool -- Note the polymorphic answertype class CpsForm t cps_t | t -> cps_t where cps :: Term t -> (Term cps_t -> Term w) -> Term w instance CpsForm t t where cps (B b) c = c (B b) cps (I b) c = c (I b) cps (Cnd p q r) c = cps p (\p' -> Cnd p' (cps q c) (cps r c)) cps (Cmp p q) c = cps p (\p' -> cps q (\q' -> c (Cmp p' q'))) shw:: Term t -> String -> String shw (B t) = ("B "++) . shows t shw (I t) = ("I "++) . shows t shw (Cnd p q r) = ("Cnd "++) . (showParen True (shw p)) . (showParen True (shw q)) . (showParen True (shw r)) shw (Cmp p q) = ("Cmp "++) . (showParen True (shw p)) . (showParen True (shw q)) term1 = Cnd (Cnd (B True) (B False) (B False)) (B True) (B False) test1 = shw (cps term1 id) "" term2 = Cnd (Cmp (Cnd (B True) (I 1) (I 2)) (I 3)) (B True) (Cmp (B True) (B False)) test2 = shw (cps term2 id) ""
Stefan Monnier wrote:
instance CpsForm t t where
This can't be right, can it?
In general no: the CPS of a function certainly doesn't fit the above pattern. So, if the source language has abstractions (the language in the original message didn't), we have to add another instance for CpsForm. Actually I started designing such a general typeful CPS of a language with abstractions, applications (and perhaps even call/cc), but then I ran out of time...
instance CpsForm t t where This can't be right, can it? In general no: the CPS of a function certainly doesn't fit the above pattern. So, if the source language has abstractions (the language in the original message didn't), we have to add another instance for CpsForm.
But any other instance will cause problem because the second type won't be functionally dependent on the first any more. Or do you suggest we remove the functional dependency? Stefan
participants (2)
-
oleg@pobox.com -
Stefan Monnier