lazy-lambda-calculus: be5ffc6e5355091df0a57c4f6ab228d9b809f5bb
1: module Data.Language.LC.Self where
2:
3: import Debug.Trace
4:
5: import Control.Monad.Partial
6: import Data.Language.LC
7: import Data.Nat
8: import Data.Typeable
9:
10: -- Lambda calculus inside lambda calculus, using Morgensen-Scott encoding
11:
12: decode :: (Encodable a) => Term a -> Partial (Val a)
13: decode = (>>= unmse) . eval
14:
15: extractC :: Partial (Val a) -> Partial (Maybe a)
16: extractC = let f (C x) = Just x
17: f _ = Nothing in
18: fmap f
19:
20: class (Typeable a) => Encodable a where
21: mse :: a -> Term b
22: unmse :: (Typeable b) => Val b -> Partial (Val a)
23:
24: instance Encodable () where
25: mse () = Lam 0
26: unmse x = cast' x >>= ($$ ())
27:
28: instance Encodable Bool where
29: mse True = Lam (Lam 1)
30: mse False = Lam (Lam 0)
31: unmse x = cast' x >>= ($$ True) >>= ($$ False)
32:
33: instance Encodable Nat where
34: mse x = let wrap Z = 1
35: wrap (S n) = 0 :@ wrap n in
36: Lam (Lam (wrap x))
37:
38: unmse x = eval' (0 :@ 1 :@ 2) [cast' x, Now (C 0), Now (F (fmap (valMap S)))]
39: {-
40: instance (Encodable a, Show a) => Encodable (Partial a) where
41: mse (Now x) = Lam (Lam (1 :@ mse x))
42: mse (Later x) = Lam (Lam (0 :@ mse x))
43:
44: unmse x = eval' (0 :@ 1 :@ 2) [Now x,
45: Now (F (\y -> do y' <- y
46: C y'' <- unmse y'
47: return (C y''))),
48: Now (F (fmap (valMap Later)))]
49:
50: instance Encodable a => Encodable [a] where
51: mse [] = Lam (Lam 1)
52: mse (x:xs) = Lam (Lam (0 :@ mse x :@ mse xs))
53:
54: instance Encodable a => Encodable (Term a) where
55: mse (Const x) = Lam (Lam (Lam (Lam (3 :@ mse x))))
56: mse (Var n) = Lam (Lam (Lam (Lam (2 :@ mse n))))
57: mse (Lam f) = Lam (Lam (Lam (Lam (1 :@ mse f))))
58: mse (l :@ r) = Lam (Lam (Lam (Lam (0 :@ mse l :@ mse r))))
59:
60: {-
61: Lookup an element in a List. We can ignore empty lists:
62:
63: selfLookup (h:t) Z = h
64: selfLookup (h:t) (S n) = selfLookup t n
65:
66: We can abstract out the recursion using a Z combinator:
67:
68: selfLookup = let f g (h:t) Z = h
69: f g (h:t) (S n) = g t n in
70: zComb f
71:
72: By definition '(h:t) A B = B h t', which eliminates the pattern-match:
73:
74: selfLookup = let f g l Z = l id (\a b -> a)
75: f g l (S n) = l id (\a b -> g b n) in
76: zComb f
77:
78: By definition 'Z A B = A' and '(S n) A B = B n', which eliminates the remaining
79: pattern-match:
80:
81: selfLookup = let f g l m = m (l id (\a b -> a))
82: (\n -> l id (\a b -> g b n)) in
83: zComb f
84:
85: Now we can put everything inline:
86:
87: selfLookup = zComb (\g l m -> m (l id (\a b -> a))
88: (\n -> l id (\a b -> g b n)))
89:
90: -}
91: selfLookup = let z = 1 :@ mse () :@ mse Z
92: s = Lam (2 :@ mse () :@ Lam (Lam (5 :@ 0 :@ 2))) in
93: zComb :@ Lam (Lam (Lam (0 :@ z :@ s)))
94: -}
Generated by git2html.