@@ -1,28 +1,32 @@
1−{-# LANGUAGE GADTs, DataKinds, KindSignatures, TypeOperators, TypeFamilies,
1+{-# LANGUAGE GADTs, DataKinds, KindSignatures, TypeOperators, TypeFamilies,
2− MultiParamTypeClasses, FlexibleInstances, PolyKinds, FlexibleContexts,
2+ MultiParamTypeClasses, FlexibleInstances, PolyKinds,
3− UndecidableInstances, ConstraintKinds, OverlappingInstances, ScopedTypeVariables,
3+ FlexibleContexts, UndecidableInstances, ConstraintKinds,
4− AllowAmbiguousTypes #-}
4+ ScopedTypeVariables, TypeInType #-}
6−module Data.Type.Set (Set(..), Union, Unionable, union, quicksort, append,
6+module Data.Type.Set (Set(..), Union, Unionable, union, quicksort, append,
7− Sort, Sortable, Append(..), Split(..), Cmp,
7+ Sort, Sortable, (:++), Split(..), Cmp, Filter, Flag(..),
8 Nub, Nubable(..), AsSet, asSet, IsSet, Subset(..),
8 Nub, Nubable(..), AsSet, asSet, IsSet, Subset(..),
9− (:->)(..), Var(..)) where
9+ Delete(..), Proxy(..), remove, Remove, (:\),
10+ Member(..), NonMember, MemberP(..)) where
11import GHC.TypeLits
12import GHC.TypeLits
12import Data.Type.Bool
13import Data.Type.Bool
13import Data.Type.Equality
14import Data.Type.Equality
16−{-| Core Set definition, in terms of lists -}
16+data Proxy (p :: k) = Proxy
18+-- Value-level 'Set' representation, essentially a list
17−data Set (n :: [*]) where
19+data Set (n :: [k]) where
20+ {--| Construct an empty set -}
18 Empty :: Set '[]
21 Empty :: Set '[]
22+ {--| Extend a set with an element -}
19 Ext :: e -> Set s -> Set (e ': s)
23 Ext :: e -> Set s -> Set (e ': s)
21instance Show (Set '[]) where
25instance Show (Set '[]) where
22 show Empty = "{}"
26 show Empty = "{}"
24instance (Show e, Show' (Set s)) => Show (Set (e ': s)) where
28instance (Show e, Show' (Set s)) => Show (Set (e ': s)) where
25− show (Ext e s) = "{" ++ show e ++ (show' s) ++ "}"
29+ show (Ext e s) = "{" ++ show e ++ (show' s) ++ "}"
27class Show' t where
31class Show' t where
28 show' :: t -> String
32 show' :: t -> String
@@ -31,6 +35,10 @@ instance Show' (Set '[]) where
31instance (Show' (Set s), Show e) => Show' (Set (e ': s)) where
35instance (Show' (Set s), Show e) => Show' (Set (e ': s)) where
32 show' (Ext e s) = ", " ++ show e ++ (show' s)
36 show' (Ext e s) = ", " ++ show e ++ (show' s)
38+instance (Eq e, Eq (Set s)) => Eq (Set (e ': s)) where
39+ (Ext e m) == (Ext e' m') = e == e' && m == m'
34{-| At the type level, normalise the list form to the set form -}
42{-| At the type level, normalise the list form to the set form -}
35type AsSet s = Nub (Sort s)
43type AsSet s = Nub (Sort s)
@@ -42,54 +50,68 @@ asSet x = nub (quicksort x)
42type IsSet s = (s ~ Nub (Sort s))
50type IsSet s = (s ~ Nub (Sort s))
44{-| Useful properties to be able to refer to someties -}
52{-| Useful properties to be able to refer to someties -}
45−type SetProperties f = (Union f '[] ~ f, Split f '[] f,
53+type SetProperties f = (Union f '[] ~ f, Split f '[] f,
46− Union '[] f ~ f, Split '[] f f,
54+ Union '[] f ~ f, Split '[] f f,
47 Union f f ~ f, Split f f f,
55 Union f f ~ f, Split f f f,
48 Unionable f '[], Unionable '[] f)
56 Unionable f '[], Unionable '[] f)
50{-- Union --}
58{-- Union --}
52{-| Union of sets -}
60{-| Union of sets -}
53−type Union s t = Nub (Sort (Append s t))
61+type Union s t = Nub (Sort (s :++ t))
55union :: (Unionable s t) => Set s -> Set t -> Set (Union s t)
63union :: (Unionable s t) => Set s -> Set t -> Set (Union s t)
56union s t = nub (quicksort (append s t))
64union s t = nub (quicksort (append s t))
58−type Unionable s t = (Sortable (Append s t), Nubable (Sort (Append s t)))
66+type Unionable s t = (Sortable (s :++ t), Nubable (Sort (s :++ t)))
60{-| List append (essentially set disjoint union) -}
68{-| List append (essentially set disjoint union) -}
61−type family Append (s :: [k]) (t :: [k]) :: [k] where
69+type family (:++) (x :: [k]) (y :: [k]) :: [k] where
62− Append '[] t = t
70+ '[] :++ xs = xs
63− Append (x ': xs) ys = x ': (Append xs ys)
71+ (x ': xs) :++ ys = x ': (xs :++ ys)
65−append :: Set s -> Set t -> Set (Append s t)
73+append :: Set s -> Set t -> Set (s :++ t)
66append Empty x = x
74append Empty x = x
67append (Ext e xs) ys = Ext e (append xs ys)
75append (Ext e xs) ys = Ext e (append xs ys)
69−{-| Useful alias for append -}
77+{-| Delete elements from a set -}
70−type (s :: [k]) :++ (t :: [k]) = Append s t
78+type family (m :: [k]) :\ (x :: k) :: [k] where
80+ (x ': xs) :\ x = xs :\ x
81+ (y ': xs) :\ x = y ': (xs :\ x)
83+class Remove s t where
84+ remove :: Set s -> Proxy t -> Set (s :\ t)
86+instance Remove '[] t where
87+ remove Empty Proxy = Empty
89+instance {-# OVERLAPS #-} Remove xs x => Remove (x ': xs) x where
90+ remove (Ext _ xs) x@Proxy = remove xs x
92+instance {-# OVERLAPPABLE #-} (((y : xs) :\ x) ~ (y : (xs :\ x)), Remove xs x)
93+ => Remove (y ': xs) x where
94+ remove (Ext y xs) (x@Proxy) = Ext y (remove xs x)
72{-| Splitting a union a set, given the sets we want to split it into -}
96{-| Splitting a union a set, given the sets we want to split it into -}
73class Split s t st where
97class Split s t st where
74 -- where st ~ Union s t
98 -- where st ~ Union s t
75− split :: Set st -> (Set s, Set t)
99+ split :: Set st -> (Set s, Set t)
77instance Split '[] '[] '[] where
101instance Split '[] '[] '[] where
78 split Empty = (Empty, Empty)
102 split Empty = (Empty, Empty)
80−instance Split s t st => Split (x ': s) (x ': t) (x ': st) where
104+instance {-# OVERLAPPABLE #-} Split s t st => Split (x ': s) (x ': t) (x ': st) where
81 split (Ext x st) = let (s, t) = split st
105 split (Ext x st) = let (s, t) = split st
82 in (Ext x s, Ext x t)
106 in (Ext x s, Ext x t)
84−instance Split s t st => Split (x ': s) t (x ': st) where
108+instance {-# OVERLAPS #-} Split s t st => Split (x ': s) t (x ': st) where
85 split (Ext x st) = let (s, t) = split st
109 split (Ext x st) = let (s, t) = split st
86− in (Ext x s, t)
110+ in (Ext x s, t)
88−instance (Split s t st) => Split s (x ': t) (x ': st) where
112+instance {-# OVERLAPS #-} (Split s t st) => Split s (x ': t) (x ': st) where
89 split (Ext x st) = let (s, t) = split st
113 split (Ext x st) = let (s, t) = split st
90− in (s, Ext x t)
114+ in (s, Ext x t)
94{-| Remove duplicates from a sorted list -}
116{-| Remove duplicates from a sorted list -}
95type family Nub t where
117type family Nub t where
@@ -99,7 +121,7 @@ type family Nub t where
99 Nub (e ': f ': s) = e ': Nub (f ': s)
121 Nub (e ': f ': s) = e ': Nub (f ': s)
101{-| Value-level counterpart to the type-level 'Nub'
123{-| Value-level counterpart to the type-level 'Nub'
102− Note: the value-level case for equal types is not define here,
124+ Note: the value-level case for equal types is not define here,
103 but should be given per-application, e.g., custom 'merging' behaviour may be required -}
125 but should be given per-application, e.g., custom 'merging' behaviour may be required -}
105class Nubable t where
127class Nubable t where
@@ -111,7 +133,10 @@ instance Nubable '[] where
111instance Nubable '[e] where
133instance Nubable '[e] where
112 nub (Ext x Empty) = Ext x Empty
134 nub (Ext x Empty) = Ext x Empty
136+instance Nubable (e ': s) => Nubable (e ': e ': s) where
137+ nub (Ext _ (Ext e s)) = nub (Ext e s)
114−instance (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
139+instance {-# OVERLAPS #-} (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
115 Nubable (f ': s)) => Nubable (e ': f ': s) where
140 Nubable (f ': s)) => Nubable (e ': f ': s) where
116 nub (Ext e (Ext f s)) = Ext e (nub (Ext f s))
141 nub (Ext e (Ext f s)) = Ext e (nub (Ext f s))
@@ -120,13 +145,13 @@ instance (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
120class Subset s t where
145class Subset s t where
121 subset :: Set t -> Set s
146 subset :: Set t -> Set s
123−instance Subset '[] '[] where
148+instance Subset '[] '[] where
124 subset xs = Empty
149 subset xs = Empty
126−instance Subset '[] (x ': t) where
151+instance {-# OVERLAPPABLE #-} Subset s t => Subset s (x ': t) where
127− subset xs = Empty
152+ subset (Ext _ xs) = subset xs
129−instance Subset s t => Subset (x ': s) (x ': t) where
154+instance {-# OVERLAPS #-} Subset s t => Subset (x ': s) (x ': t) where
130 subset (Ext x xs) = Ext x (subset xs)
155 subset (Ext x xs) = Ext x (subset xs)
@@ -139,8 +164,17 @@ data Flag = FMin | FMax
140type family Filter (f :: Flag) (p :: k) (xs :: [k]) :: [k] where
165type family Filter (f :: Flag) (p :: k) (xs :: [k]) :: [k] where
141 Filter f p '[] = '[]
166 Filter f p '[] = '[]
142− Filter FMin p (x ': xs) = If (Cmp x p == LT) (x ': (Filter FMin p xs)) (Filter FMin p xs)
167+ Filter FMin p (x ': xs) = If (Cmp x p == LT) (x ': (Filter FMin p xs)) (Filter FMin p xs)
143− Filter FMax p (x ': xs) = If (Cmp x p == GT || Cmp x p == EQ) (x ': (Filter FMax p xs)) (Filter FMax p xs)
168+ Filter FMax p (x ': xs) = If (Cmp x p == GT || Cmp x p == EQ) (x ': (Filter FMax p xs)) (Filter FMax p xs)
170+type family DeleteFromList (e :: elem) (list :: [elem]) where
171+ DeleteFromList elem '[] = '[]
172+ DeleteFromList elem (x ': xs) = If (Cmp elem x == EQ)
174+ (x ': DeleteFromList elem xs)
176+type family Delete elem set where
177+ Delete elem (Set xs) = Set (DeleteFromList elem xs)
145{-| Value-level quick sort that respects the type-level ordering -}
179{-| Value-level quick sort that respects the type-level ordering -}
146class Sortable xs where
180class Sortable xs where
@@ -164,11 +198,11 @@ instance FilterV f p '[] where
165instance (Conder ((Cmp x p) == LT), FilterV FMin p xs) => FilterV FMin p (x ': xs) where
199instance (Conder ((Cmp x p) == LT), FilterV FMin p xs) => FilterV FMin p (x ': xs) where
166 filterV f@Proxy p (Ext x xs) = cond (Proxy::(Proxy ((Cmp x p) == LT)))
200 filterV f@Proxy p (Ext x xs) = cond (Proxy::(Proxy ((Cmp x p) == LT)))
167− (Ext x (filterV f p xs)) (filterV f p xs)
201+ (Ext x (filterV f p xs)) (filterV f p xs)
169instance (Conder (((Cmp x p) == GT) || ((Cmp x p) == EQ)), FilterV FMax p xs) => FilterV FMax p (x ': xs) where
203instance (Conder (((Cmp x p) == GT) || ((Cmp x p) == EQ)), FilterV FMax p xs) => FilterV FMax p (x ': xs) where
170 filterV f@Proxy p (Ext x xs) = cond (Proxy::(Proxy (((Cmp x p) == GT) || ((Cmp x p) == EQ))))
204 filterV f@Proxy p (Ext x xs) = cond (Proxy::(Proxy (((Cmp x p) == GT) || ((Cmp x p) == EQ))))
171− (Ext x (filterV f p xs)) (filterV f p xs)
205+ (Ext x (filterV f p xs)) (filterV f p xs)
173class Conder g where
207class Conder g where
174 cond :: Proxy g -> Set s -> Set t -> Set (If g s t)
208 cond :: Proxy g -> Set s -> Set t -> Set (If g s t)
@@ -183,30 +217,20 @@ instance Conder False where
184type family Cmp (a :: k) (b :: k) :: Ordering
218type family Cmp (a :: k) (b :: k) :: Ordering
186−{-| Pair a symbol (represetning a variable) with a type -}
220+{-| Membership of an element in a set, with an acommanying
187−infixl 2 :->
221+ value-level function that returns a bool -}
188−data (k :: Symbol) :-> (v :: *) = (Var k) :-> v
222+class Member a s where
189−
223+ member :: Proxy a -> Set s -> Bool
190−data Var (k :: Symbol) where Var :: Var k
224+
191− {-| Some special defaults for some common names -}
225+instance {-# OVERLAPS #-} Member a (a ': s) where
192− X :: Var "x"
226+ member _ (Ext x _) = True
194− Z :: Var "z"
228+instance {-# OVERLAPPABLE #-} Member a s => Member a (b ': s) where
195−
229+ member a (Ext _ xs) = member a xs
197−instance (Show (Var k), Show v) => Show (k :-> v) where
231+type family MemberP a s :: Bool where
198− show (k :-> v) = "(" ++ show k ++ " :-> " ++ show v ++ ")"
232+ MemberP a '[] = False
199−instance Show (Var "x") where
233+ MemberP a (a ': s) = True
200− show X = "x"
234+ MemberP a (b ': s) = MemberP a s
201− show Var = "Var"
235+
202−instance Show (Var "y") where
236+type NonMember a s = MemberP a s ~ False
205−instance Show (Var "z") where
208−instance Show (Var v) where
211−{-| Symbol comparison -}
212−type instance Cmp (v :-> a) (u :-> b) = CmpSymbol v u