@@ -5,13 +5,14 @@ The implementation is similar to that shown in the paper.
5{-# LANGUAGE TypeOperators, PolyKinds, DataKinds, KindSignatures,
5{-# LANGUAGE TypeOperators, PolyKinds, DataKinds, KindSignatures,
6 TypeFamilies, UndecidableInstances, MultiParamTypeClasses,
6 TypeFamilies, UndecidableInstances, MultiParamTypeClasses,
7 FlexibleInstances, GADTs, FlexibleContexts, ScopedTypeVariables,
7 FlexibleInstances, GADTs, FlexibleContexts, ScopedTypeVariables,
8− ConstraintKinds #-}
8+ ConstraintKinds, IncoherentInstances #-}
10module Data.Type.Map (Mapping(..), Union, Unionable, union, Var(..), Map(..),
10module Data.Type.Map (Mapping(..), Union, Unionable, union, Var(..), Map(..),
11 Combine, Combinable(..), Cmp,
11 Combine, Combinable(..), Cmp,
12 Nubable, nub,
12 Nubable, nub,
13 Lookup, Member, (:\), Split, split,
13 Lookup, Member, (:\), Split, split,
14+ IsMember, lookp, Updatable, update,
14− IsMap, AsMap, asMap,
15+ IsMap, AsMap, asMap,
15 Submap, submap) where
16 Submap, submap) where
17import GHC.TypeLits
18import GHC.TypeLits
@@ -45,17 +46,17 @@ type family Combine (a :: v) (b :: v) :: v
46{-| Delete elements from a map by key -}
47{-| Delete elements from a map by key -}
47type family (m :: [Mapping k v]) :\ (c :: k) :: [Mapping k v] where
48type family (m :: [Mapping k v]) :\ (c :: k) :: [Mapping k v] where
48− '[] :\ k = '[]
49+ '[] :\ k = '[]
49− ((k :-> v) ': m) :\ k = m :\ k
50+ ((k :-> v) ': m) :\ k = m :\ k
50− (kvp ': m) :\ k = kvp ': (m :\ k)
51+ (kvp ': m) :\ k = kvp ': (m :\ k)
52−{-| Lookup elements from a map -}
53+{-| Type-level lookup of elements from a map -}
53type family Lookup (m :: [Mapping k v]) (c :: k) :: Maybe v where
54type family Lookup (m :: [Mapping k v]) (c :: k) :: Maybe v where
54 Lookup '[] k = Nothing
55 Lookup '[] k = Nothing
55 Lookup ((k :-> v) ': m) k = Just v
56 Lookup ((k :-> v) ': m) k = Just v
56 Lookup (kvp ': m) k = Lookup m k
57 Lookup (kvp ': m) k = Lookup m k
58−{-| Membership test -}
59+{-| Membership test as type function -}
59type family Member (c :: k) (m :: [Mapping k v]) :: Bool where
60type family Member (c :: k) (m :: [Mapping k v]) :: Bool where
60 Member k '[] = False
61 Member k '[] = False
61 Member k ((k :-> v) ': m) = True
62 Member k ((k :-> v) ': m) = True
@@ -75,6 +76,37 @@ data Map (n :: [Mapping Symbol *]) where
75 Empty :: Map '[]
76 Empty :: Map '[]
76 Ext :: Var k -> v -> Map m -> Map ((k :-> v) ': m)
77 Ext :: Var k -> v -> Map m -> Map ((k :-> v) ': m)
79+{-| Membership test a type class (predicate) -}
80+class IsMember v t m where
81+ {-| Value-level lookup of elements from a map, via type class predicate -}
82+ lookp :: Var v -> Map m -> t
84+instance {-# OVERLAPS #-} IsMember v t ((v ':-> t) ': m) where
85+ lookp _ (Ext _ x _) = x
87+instance {-# OVERLAPPABLE #-} IsMember v t m => IsMember v t (x ': m) where
88+ lookp v (Ext _ _ m) = lookp v m
91+{-| Updatability as a type class -}
92+class Updatable v t m n where
93+ {-| Update a map with `m` at variable `v` with a value of type `t`
94+ to produce a map of type `n` -}
95+ update :: Map m -> Var v -> t -> Map n
97+instance {-# OVERLAPS #-} Updatable v t ((v ':-> s) ': m) ((v ':-> t) ': m) where
98+ update (Ext v _ m) _ x = Ext v x m
100+instance Updatable v t m n => Updatable v t ((w ':-> y) ': m) ((w ':-> y) ': n) where
101+ update (Ext w y m) v x = Ext w y (update m v x)
103+-- instance Updatable v t '[] '[v ':-> t] where
104+-- update Empty v x = Ext v x Empty
106+instance Updatable v t s ((v ':-> t) ': s) where
107+ update xs v x = Ext v x xs
78{-| Predicate to check if in normalised map form -}
110{-| Predicate to check if in normalised map form -}
79type IsMap s = (s ~ Nub (Sort s))
111type IsMap s = (s ~ Nub (Sort s))
@@ -89,7 +121,7 @@ instance Show (Map '[]) where
89 show Empty = "{}"
121 show Empty = "{}"
91instance (KnownSymbol k, Show v, Show' (Map s)) => Show (Map ((k :-> v) ': s)) where
123instance (KnownSymbol k, Show v, Show' (Map s)) => Show (Map ((k :-> v) ': s)) where
92− show (Ext k v s) = "{" ++ show k ++ " :-> " ++ show v ++ (show' s) ++ "}"
124+ show (Ext k v s) = "{" ++ show k ++ " :-> " ++ show v ++ show' s ++ "}"
94class Show' t where
126class Show' t where
95 show' :: t -> String
127 show' :: t -> String
@@ -98,12 +130,25 @@ instance Show' (Map '[]) where
98instance (KnownSymbol k, Show v, Show' (Map s)) => Show' (Map ((k :-> v) ': s)) where
130instance (KnownSymbol k, Show v, Show' (Map s)) => Show' (Map ((k :-> v) ': s)) where
99 show' (Ext k v s) = ", " ++ show k ++ " :-> " ++ show v ++ (show' s)
131 show' (Ext k v s) = ", " ++ show k ++ " :-> " ++ show v ++ (show' s)
133+instance Eq (Map '[]) where
134+ Empty == Empty = True
136+instance (Eq v, Eq (Map s)) => Eq (Map ((k :-> v) ': s)) where
137+ (Ext Var v m) == (Ext Var v' m') = v == v' && m == m'
139+instance Ord (Map '[]) where
140+ compare Empty Empty = EQ
142+instance (Ord v, Ord (Map s)) => Ord (Map ((k :-> v) ': s)) where
143+ compare (Ext Var v m) (Ext Var v' m') = compare v v' `mappend` compare m m'
101−{-| Union of two finite maps -}
145+{-| Union of two finite maps (normalising) -}
102union :: (Unionable s t) => Map s -> Map t -> Map (Union s t)
146union :: (Unionable s t) => Map s -> Map t -> Map (Union s t)
103union s t = nub (quicksort (append s t))
147union s t = nub (quicksort (append s t))
105type Unionable s t = (Nubable (Sort (s :++ t)), Sortable (s :++ t))
149type Unionable s t = (Nubable (Sort (s :++ t)), Sortable (s :++ t))
151+{-| Append of two finite maps (non normalising) -}
107append :: Map s -> Map t -> Map (s :++ t)
152append :: Map s -> Map t -> Map (s :++ t)
108append Empty x = x
153append Empty x = x
109append (Ext k v xs) ys = Ext k v (append xs ys)
154append (Ext k v xs) ys = Ext k v (append xs ys)
@@ -118,11 +163,15 @@ class Sortable xs where
118instance Sortable '[] where
163instance Sortable '[] where
119 quicksort Empty = Empty
164 quicksort Empty = Empty
121−instance (Sortable (Filter FMin (k :-> v) xs),
166+instance (Sortable (Filter FMin (k :-> v) xs)
167+ , Sortable (Filter FMax (k :-> v) xs)
168+ , FilterV FMin k v xs
122− Sortable (Filter FMax (k :-> v) xs), FilterV FMin k v xs, FilterV FMax k v xs) => Sortable ((k :-> v) ': xs) where
169+ , FilterV FMax k v xs) => Sortable ((k :-> v) ': xs) where
170+ quicksort (Ext k v xs) =
123− quicksort (Ext k v xs) = ((quicksort (less k v xs)) `append` (Ext k v Empty)) `append` (quicksort (more k v xs))
171+ quicksort (less k v xs) `append` Ext k v Empty `append` quicksort (more k v xs)
124− where less = filterV (Proxy::(Proxy FMin))
173+ less = filterV (Proxy::(Proxy FMin))
125− more = filterV (Proxy::(Proxy FMax))
174+ more = filterV (Proxy::(Proxy FMax))
127{- Filter out the elements less-than or greater-than-or-equal to the pivot -}
176{- Filter out the elements less-than or greater-than-or-equal to the pivot -}
128class FilterV (f::Flag) k v xs where
177class FilterV (f::Flag) k v xs where
@@ -131,13 +180,19 @@ class FilterV (f::Flag) k v xs where
131instance FilterV f k v '[] where
180instance FilterV f k v '[] where
132 filterV _ k v Empty = Empty
181 filterV _ k v Empty = Empty
134−instance (Conder ((Cmp x (k :-> v)) == LT), FilterV FMin k v xs) => FilterV FMin k v (x ': xs) where
183+instance (Conder (Cmp x (k :-> v) == LT), FilterV FMin k v xs) => FilterV FMin k v (x ': xs) where
135− filterV f@Proxy k v (Ext k' v' xs) = cond (Proxy::(Proxy ((Cmp x (k :-> v)) == LT)))
184+ filterV f@Proxy k v (Ext k' v' xs) =
185+ cond (Proxy::(Proxy (Cmp x (k :-> v) == LT)))
136− (Ext k' v' (filterV f k v xs)) (filterV f k v xs)
186+ (Ext k' v' (filterV f k v xs))
138−instance (Conder (((Cmp x (k :-> v)) == GT) || ((Cmp x (k :-> v)) == EQ)), FilterV FMax k v xs) => FilterV FMax k v (x ': xs) where
190+ (Conder ((Cmp x (k :-> v) == GT) || (Cmp x (k :-> v) == EQ)), FilterV FMax k v xs)
191+ => FilterV FMax k v (x ': xs) where
192+ filterV f@Proxy k v (Ext k' v' xs) =
139− filterV f@Proxy k v (Ext k' v' xs) = cond (Proxy::(Proxy (((Cmp x (k :-> v)) == GT) || ((Cmp x (k :-> v)) == EQ))))
193+ cond (Proxy::(Proxy ((Cmp x (k :-> v) == GT) || (Cmp x (k :-> v) == EQ))))
140− (Ext k' v' (filterV f k v xs)) (filterV f k v xs)
194+ (Ext k' v' (filterV f k v xs))
142class Combinable t t' where
197class Combinable t t' where
143 combine :: t -> t' -> Combine t t'
198 combine :: t -> t' -> Combine t t'
@@ -151,13 +206,14 @@ instance Nubable '[] where
151instance Nubable '[e] where
206instance Nubable '[e] where
152 nub (Ext k v Empty) = Ext k v Empty
207 nub (Ext k v Empty) = Ext k v Empty
154−instance {-# OVERLAPABLE #-}
209+instance {-# OVERLAPPABLE #-}
155 (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
210 (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
156 Nubable (f ': s)) => Nubable (e ': f ': s) where
211 Nubable (f ': s)) => Nubable (e ': f ': s) where
157 nub (Ext k v (Ext k' v' s)) = Ext k v (nub (Ext k' v' s))
212 nub (Ext k v (Ext k' v' s)) = Ext k v (nub (Ext k' v' s))
159instance {-# OVERLAPS #-}
214instance {-# OVERLAPS #-}
160− (Combinable v v', Nubable ((k :-> Combine v v') ': s)) => Nubable ((k :-> v) ': (k :-> v') ': s) where
215+ (Combinable v v', Nubable ((k :-> Combine v v') ': s))
216+ => Nubable ((k :-> v) ': (k :-> v') ': s) where
161 nub (Ext k v (Ext k' v' s)) = nub (Ext k (combine v v') s)
217 nub (Ext k v (Ext k' v' s)) = nub (Ext k (combine v v') s)