-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathKeyIM.hs
More file actions
89 lines (62 loc) · 2.32 KB
/
Copy pathKeyIM.hs
File metadata and controls
89 lines (62 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{-# LANGUAGE GADTs, AllowAmbiguousTypes, RankNTypes, DataKinds, TypeOperators, PolyKinds, TypeFamilies, UndecidableInstances #-}
import HList
import Data.Type.Equality
import Control.Applicative
import Control.Monad
data Tree a = Leaf a | (Tree a) :++: (Tree a)
data p `Sub` w where
Start :: w `Sub` w
LeftChild :: (l :++: r) `Sub` w -> l `Sub` w
RightChild :: (l :++: r) `Sub` w -> r `Sub` w
testEq :: forall a b w. a `Sub` w -> b `Sub` w -> Maybe (a :~: b)
testEq Start Start = Just Refl
testEq (LeftChild l) (LeftChild r) = weakenL <$> testEq l r
testEq (RightChild l) (RightChild r) = weakenR <$> testEq l r
testEq _ _ = Nothing
weakenL :: ((l :++: r) :~: (l' :++: r')) -> l :~: l'
weakenL x = case x of Refl -> Refl
weakenR :: ((l :++: r) :~: (l' :++: r')) -> r :~: r'
weakenR x = case x of Refl -> Refl
type TName s a = Leaf a `Sub` s
type TNameSupply p s = Sub p s
newTNameSupply :: TNameSupply s s
newTNameSupply = Start
tsplit :: TNameSupply (l :++: r) s -> (TNameSupply l s, TNameSupply r s)
tsplit s = (LeftChild s, RightChild s)
supplyTName :: TNameSupply (Leaf a) s -> TName s a
supplyTName = id
data Key s a = Key (Sub (Leaf a) s)
instance TestEquality (Key s) where
testEquality (Key l) (Key r) =
case testEq l r of
Just Refl -> Just Refl
Nothing -> Nothing
data KeyIm p s a = KeyIm { getKeyIm :: TNameSupply p s -> a }
newKeyIm :: KeyIm (Leaf a) s (Key s a)
newKeyIm = KeyIm $ \s -> Key (supplyTName s)
ireturn :: a -> KeyIm l s a
ireturn x = KeyIm $ \_ -> x
(.>>=) :: KeyIm l s a -> (a -> KeyIm r s b) -> KeyIm (l :++: r) s b
m .>>= f = KeyIm $ \s ->
let (sl,sr) = tsplit s
in getKeyIm (f (getKeyIm m sl)) sr
runKeyIm :: (forall s. KeyIm l s a) -> a
runKeyIm (KeyIm f) = f newTNameSupply
{-
data KeyM s a where
KeyM :: KeyIm l s a -> KeyM s a
newKey :: KeyM s (Key s a)
newKey = KeyM $ newKeyIm
runKeyM :: (forall s. KeyM s a) -> a
runKeyM m = case m of
KeyM f -> runKeyIm (unsafeCoerce f)
instance Functor (KeyM s) where fmap = liftM
instance Applicative (KeyM s) where pure = return; (<*>) = ap
instance Monad (KeyM s) where
return = KeyM . ireturn
m >>= f =
case m of
KeyM m' -> KeyM $ m' .>>= \x ->
case f x of
KeyM f' -> unsafeCoerce f'
-}