PHOAS tagless interpretation with type family on Var

Anonymous Coward 2018-03-07 17:39:53.783393 UTC

1newtype Eval a = E { eval :: a }
2newtype (Show a) => PPrint a = PP { pprint :: String }
3newtype Desugar repr a = D { desugar :: repr a }
4
5
6type family Var (repr :: * -> *) a
7type instance Var Eval a = a
8type instance Var PPrint a = String
9type instance Var (Desugar repr) a = Var repr a
10
11
12class PHOAS (repr :: * -> *) where
13 varP :: Var repr a -> repr a
14 lamP :: (Var repr a -> repr b) -> repr (a -> b)
15 appP :: repr (a -> b) -> repr a -> repr b
16 liftP :: a -> repr a
17
18
19instance (PHOAS repr) => PHOAS (Desugar repr) where
20 varP = varP
21 lamP = lamP
22 appP = appP
23 liftP = liftP
24
25
26instance PHOAS Eval where
27 varP = E
28 lamP f = E (eval . f)
29 appP x y = E . eval x $ eval y
30 liftP = E
31
32foo = lamP $ \x -> varP x
33
34x = eval foo 10
35y = eval (desugar foo) 10
36
37-- x evaluates
38-- y loops forever