git.iko.soy/type-level-sets
on master help sign in
8 files changed+218−81
since splitsnapshots
unifiedsplit
README+42−21 changelog.md+5 example.hs+5−5 example2.hs+9 src/Data/Type/Map.hs+78−22 src/Data/Type/Set.hs+47−7 stack.yaml+1−1 type-level-sets.cabal+31−25
README+42−21
@@ -1,35 +1,56 @@
1−This library provides type-level sets to Haskell, with a value level counterpart, and operations for taking the union, computing
2−subsets, and split sets. Also included is a "mapping" type constructor that pairs symbols with types. This can be used to represent
3−sets of variable-type pairs, which is used in the paper "Embedding effect systems in Haskell" (Dominic Orchard,
1+This library provides type-level sets and finite maps to Haskell, with a value level counterpart, and operations for taking the union, computing
2+subsets/submaps, and splitting sets/maps. This library was originally built based on
3+"Embedding effect systems in Haskell" (Dominic Orchard,
44Tomas Petricek <http://www.cl.cam.ac.uk/~dao29/publ/haskell14-effects.pdf>) to embed effect sets.
55
66The following shows an example:
77
8− {-# LANGUAGE DataKinds, TypeOperators #-}
8+ {-# LANGUAGE DataKinds, TypeOperators, TypeFamilies, MultiParamTypeClasses #-}
9+ import Data.Type.Map
10+
11+ -- Specifies how to combine duplicate key-value pairs for Int values
12+ type instance Combine Int Int = Int
13+ instance Combinable Int Int where
14+ combine x y = x + y
15+
16+ foo :: Map '["x" :-> Int, "z" :-> Bool, "w" :-> Int]
17+ foo = Ext (Var :: (Var "x")) 2
18+ $ Ext (Var :: (Var "z")) True
19+ $ Ext (Var :: (Var "w")) 5
20+ Empty
21+
22+ bar :: Map '["y" :-> Int, "w" :-> Int]
23+ bar = Ext (Var :: (Var "y")) 3
24+ $ Ext (Var :: (Var "w")) 1
25+ $ Empty
26+
27+ -- foobar :: Map '["w" :-> Int, "x" :-> Int, "y" :-> Int, "z" :-> Bool]
28+ foobar = foo `union` bar
29+
30+The 'Map' type for 'foobar' here shows the normalised form (sorted with no duplicates).
31+The type signatures is commented out as it can be infered. Running the example we get:
932
10− import Data.Type.Set
33+ *Main> foobar
34+ {w :-> 6, x :-> 2, y :-> 3, z :-> True}
1135
12− foo :: Set '["x" :-> Int, "z" :-> Int, "w" :-> Int]
13− foo = Ext ((Var :: (Var "x")) :-> 2) $
14− Ext ((Var :: (Var "z")) :-> 4) $
15− Ext ((Var :: (Var "w")) :-> 5) $
16− Empty
36+Thus, we see that values for 'w' are added.
1737
18− bar :: Set '["y" :-> Int, "w" :-> Int]
19− bar = Ext ((Var :: (Var "y")) :-> 3) $
20− Ext ((Var :: (Var "w")) :-> 1) $
21− Empty
38+ import GHC.TypeLits
39+ import Data.Type.Set
40+ type instance Cmp (Natural n) (Natural m) = CmpNat n m
2241
23− -- foobar :: Set '["w" :-> Int, "x" :-> Int, "y" :-> Int, "z" :-> Int]
24− foobar = foo `union` bar
42+ data Natural (a :: Nat) where
43+ Z :: Natural 0
44+ S :: Natural n -> Natural (n + 1)
2545
26−The 'Set' type for 'foobar' here shows the normalised form (sorted with no duplicates).
27−The type signatures is commented out as it can be infered. Running the example we get:
46+ -- foo :: Set '[Natural 0, Natural 1, Natural 3]
47+ foo = asSet $ Ext (S Z) (Ext (S (S (S Z))) (Ext Z Empty))
2848
29− *Main> foobar
30− {(Var :-> 1), (Var :-> 2), (Var :-> 3), (Var :-> 4)}
49+ -- bar :: Set '[Natural 1, Natural 2]
50+ bar = asSet $ Ext (S (S Z)) (Ext (S Z) (Ext (S Z) Empty))
3151
32−Thus, we see that the first value paired with the "w" variable is dropped.
52+ -- foobar :: Set '[Natural 0, Natural 1, Natural 2, Natural 3]
53+ foobar = foo `union` bar
3354
3455
3556
changelog.mdnew file+5
@@ -0,0 +1,5 @@
1+ # v0.8.9.0
2+
3+ - GHC 8.4 and 8.6 support.
4+ - Fixed bug in the delete operation.
5+ - Non-membership predicates
example.hs+5−5
@@ -1,4 +1,4 @@
1−{-# LANGUAGE DataKinds, TypeOperators, KindSignatures, TypeFamilies, MultiParamTypeClasses #-}
1+{-# LANGUAGE DataKinds, TypeOperators, TypeFamilies, MultiParamTypeClasses #-}
22
33import GHC.TypeLits
44import Data.Type.Map
@@ -10,10 +10,10 @@ instance Combinable Int Int where
1010 combine x y = x + y
1111
1212foo :: Map '["x" :-> Int, "z" :-> Bool, "w" :-> Int]
13−foo = Ext (Var :: (Var "x")) 2 $
14− Ext (Var :: (Var "z")) True $
15− Ext (Var :: (Var "w")) 5 $
16− Empty
13+foo = Ext (Var :: (Var "x")) 2
14+ $ Ext (Var :: (Var "z")) True
15+ $ Ext (Var :: (Var "w")) 5
16+ $ Empty
1717
1818foo' :: Map (AsMap '["z" :-> Bool, "x" :-> Int, "w" :-> Int])
1919foo' = asMap foo
example2.hs+9
@@ -1,4 +1,5 @@
11{-# LANGUAGE DataKinds, TypeOperators, TypeFamilies, GADTs, StandaloneDeriving #-}
2+{-# LANGUAGE FlexibleContexts #-}
23
34import GHC.TypeLits
45import Data.Type.Set
@@ -19,3 +20,11 @@ bar = asSet $ Ext (S (S Z)) (Ext (S Z) (Ext (S Z) Empty))
1920
2021-- foobar :: Set '[Natural 0, Natural 1, Natural 2, Natural 3]
2122foobar = foo `union` bar
23+
24+nonMemberTest :: NonMember (Natural 0) as => Set as -> ()
25+nonMemberTest set = ()
26+
27+-- nonMemberTest meep is well typed
28+meep = asSet $ Ext (S Z) (Ext (S (S Z)) Empty)
29+-- nonMemberTest morp is ill typed
30+morp = asSet $ Ext (S Z) (Ext (S (S Z)) (Ext Z Empty))
src/Data/Type/Map.hs+78−22
@@ -5,13 +5,14 @@ The implementation is similar to that shown in the paper.
55{-# LANGUAGE TypeOperators, PolyKinds, DataKinds, KindSignatures,
66 TypeFamilies, UndecidableInstances, MultiParamTypeClasses,
77 FlexibleInstances, GADTs, FlexibleContexts, ScopedTypeVariables,
8− ConstraintKinds #-}
8+ ConstraintKinds, IncoherentInstances #-}
99
1010module Data.Type.Map (Mapping(..), Union, Unionable, union, Var(..), Map(..),
1111 Combine, Combinable(..), Cmp,
1212 Nubable, nub,
1313 Lookup, Member, (:\), Split, split,
14− IsMap, AsMap, asMap,
14+ IsMember, lookp, Updatable, update,
15+ IsMap, AsMap, asMap,
1516 Submap, submap) where
1617
1718import GHC.TypeLits
@@ -45,17 +46,17 @@ type family Combine (a :: v) (b :: v) :: v
4546
4647{-| Delete elements from a map by key -}
4748type family (m :: [Mapping k v]) :\ (c :: k) :: [Mapping k v] where
48− '[] :\ k = '[]
49− ((k :-> v) ': m) :\ k = m :\ k
50− (kvp ': m) :\ k = kvp ': (m :\ k)
49+ '[] :\ k = '[]
50+ ((k :-> v) ': m) :\ k = m :\ k
51+ (kvp ': m) :\ k = kvp ': (m :\ k)
5152
52−{-| Lookup elements from a map -}
53+{-| Type-level lookup of elements from a map -}
5354type family Lookup (m :: [Mapping k v]) (c :: k) :: Maybe v where
5455 Lookup '[] k = Nothing
5556 Lookup ((k :-> v) ': m) k = Just v
5657 Lookup (kvp ': m) k = Lookup m k
5758
58−{-| Membership test -}
59+{-| Membership test as type function -}
5960type family Member (c :: k) (m :: [Mapping k v]) :: Bool where
6061 Member k '[] = False
6162 Member k ((k :-> v) ': m) = True
@@ -75,6 +76,37 @@ data Map (n :: [Mapping Symbol *]) where
7576 Empty :: Map '[]
7677 Ext :: Var k -> v -> Map m -> Map ((k :-> v) ': m)
7778
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
83+
84+instance {-# OVERLAPS #-} IsMember v t ((v ':-> t) ': m) where
85+ lookp _ (Ext _ x _) = x
86+
87+instance {-# OVERLAPPABLE #-} IsMember v t m => IsMember v t (x ': m) where
88+ lookp v (Ext _ _ m) = lookp v m
89+
90+
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
96+
97+instance {-# OVERLAPS #-} Updatable v t ((v ':-> s) ': m) ((v ':-> t) ': m) where
98+ update (Ext v _ m) _ x = Ext v x m
99+
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)
102+
103+-- instance Updatable v t '[] '[v ':-> t] where
104+-- update Empty v x = Ext v x Empty
105+
106+instance Updatable v t s ((v ':-> t) ': s) where
107+ update xs v x = Ext v x xs
108+
109+
78110{-| Predicate to check if in normalised map form -}
79111type IsMap s = (s ~ Nub (Sort s))
80112
@@ -89,7 +121,7 @@ instance Show (Map '[]) where
89121 show Empty = "{}"
90122
91123instance (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 ++ "}"
93125
94126class Show' t where
95127 show' :: t -> String
@@ -98,12 +130,25 @@ instance Show' (Map '[]) where
98130instance (KnownSymbol k, Show v, Show' (Map s)) => Show' (Map ((k :-> v) ': s)) where
99131 show' (Ext k v s) = ", " ++ show k ++ " :-> " ++ show v ++ (show' s)
100132
101−{-| Union of two finite maps -}
133+instance Eq (Map '[]) where
134+ Empty == Empty = True
135+
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'
138+
139+instance Ord (Map '[]) where
140+ compare Empty Empty = EQ
141+
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'
144+
145+{-| Union of two finite maps (normalising) -}
102146union :: (Unionable s t) => Map s -> Map t -> Map (Union s t)
103147union s t = nub (quicksort (append s t))
104148
105149type Unionable s t = (Nubable (Sort (s :++ t)), Sortable (s :++ t))
106150
151+{-| Append of two finite maps (non normalising) -}
107152append :: Map s -> Map t -> Map (s :++ t)
108153append Empty x = x
109154append (Ext k v xs) ys = Ext k v (append xs ys)
@@ -118,11 +163,15 @@ class Sortable xs where
118163instance Sortable '[] where
119164 quicksort Empty = Empty
120165
121−instance (Sortable (Filter 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
123− quicksort (Ext k v xs) = ((quicksort (less k v xs)) `append` (Ext k v Empty)) `append` (quicksort (more k v xs))
124− where less = filterV (Proxy::(Proxy FMin))
125− more = filterV (Proxy::(Proxy FMax))
166+instance (Sortable (Filter FMin (k :-> v) xs)
167+ , Sortable (Filter FMax (k :-> v) xs)
168+ , FilterV FMin k v xs
169+ , FilterV FMax k v xs) => Sortable ((k :-> v) ': xs) where
170+ quicksort (Ext k v xs) =
171+ quicksort (less k v xs) `append` Ext k v Empty `append` quicksort (more k v xs)
172+ where
173+ less = filterV (Proxy::(Proxy FMin))
174+ more = filterV (Proxy::(Proxy FMax))
126175
127176{- Filter out the elements less-than or greater-than-or-equal to the pivot -}
128177class FilterV (f::Flag) k v xs where
@@ -131,13 +180,19 @@ class FilterV (f::Flag) k v xs where
131180instance FilterV f k v '[] where
132181 filterV _ k v Empty = Empty
133182
134−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)))
136− (Ext k' v' (filterV f k v xs)) (filterV f k v xs)
183+instance (Conder (Cmp x (k :-> v) == LT), FilterV FMin k v xs) => FilterV FMin k v (x ': xs) where
184+ filterV f@Proxy k v (Ext k' v' xs) =
185+ cond (Proxy::(Proxy (Cmp x (k :-> v) == LT)))
186+ (Ext k' v' (filterV f k v xs))
187+ (filterV f k v xs)
137188
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
139− filterV f@Proxy k v (Ext k' v' xs) = 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)
189+instance
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) =
193+ cond (Proxy::(Proxy ((Cmp x (k :-> v) == GT) || (Cmp x (k :-> v) == EQ))))
194+ (Ext k' v' (filterV f k v xs))
195+ (filterV f k v xs)
141196
142197class Combinable t t' where
143198 combine :: t -> t' -> Combine t t'
@@ -151,13 +206,14 @@ instance Nubable '[] where
151206instance Nubable '[e] where
152207 nub (Ext k v Empty) = Ext k v Empty
153208
154−instance {-# OVERLAPABLE #-}
209+instance {-# OVERLAPPABLE #-}
155210 (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
156211 Nubable (f ': s)) => Nubable (e ': f ': s) where
157212 nub (Ext k v (Ext k' v' s)) = Ext k v (nub (Ext k' v' s))
158213
159214instance {-# 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
161217 nub (Ext k v (Ext k' v' s)) = nub (Ext k (combine v v') s)
162218
163219
src/Data/Type/Set.hs+47−7
@@ -1,12 +1,13 @@
11{-# LANGUAGE GADTs, DataKinds, KindSignatures, TypeOperators, TypeFamilies,
22 MultiParamTypeClasses, FlexibleInstances, PolyKinds,
33 FlexibleContexts, UndecidableInstances, ConstraintKinds,
4− ScopedTypeVariables #-}
4+ ScopedTypeVariables, TypeInType #-}
55
66module Data.Type.Set (Set(..), Union, Unionable, union, quicksort, append,
77 Sort, Sortable, (:++), Split(..), Cmp, Filter, Flag(..),
88 Nub, Nubable(..), AsSet, asSet, IsSet, Subset(..),
9− Delete(..), Proxy(..)) where
9+ Delete(..), Proxy(..), remove, Remove, (:\),
10+ Member(..), NonMember, MemberP(..)) where
1011
1112import GHC.TypeLits
1213import Data.Type.Bool
@@ -15,7 +16,7 @@ import Data.Type.Equality
1516data Proxy (p :: k) = Proxy
1617
1718-- Value-level 'Set' representation, essentially a list
18−data Set (n :: [*]) where
19+data Set (n :: [k]) where
1920 {--| Construct an empty set -}
2021 Empty :: Set '[]
2122 {--| Extend a set with an element -}
@@ -34,6 +35,10 @@ instance Show' (Set '[]) where
3435instance (Show' (Set s), Show e) => Show' (Set (e ': s)) where
3536 show' (Ext e s) = ", " ++ show e ++ (show' s)
3637
38+instance (Eq e, Eq (Set s)) => Eq (Set (e ': s)) where
39+ (Ext e m) == (Ext e' m') = e == e' && m == m'
40+
41+
3742{-| At the type level, normalise the list form to the set form -}
3843type AsSet s = Nub (Sort s)
3944
@@ -69,6 +74,25 @@ append :: Set s -> Set t -> Set (s :++ t)
6974append Empty x = x
7075append (Ext e xs) ys = Ext e (append xs ys)
7176
77+{-| Delete elements from a set -}
78+type family (m :: [k]) :\ (x :: k) :: [k] where
79+ '[] :\ x = '[]
80+ (x ': xs) :\ x = xs :\ x
81+ (y ': xs) :\ x = y ': (xs :\ x)
82+
83+class Remove s t where
84+ remove :: Set s -> Proxy t -> Set (s :\ t)
85+
86+instance Remove '[] t where
87+ remove Empty Proxy = Empty
88+
89+instance {-# OVERLAPS #-} Remove xs x => Remove (x ': xs) x where
90+ remove (Ext _ xs) x@Proxy = remove xs x
91+
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)
95+
7296{-| Splitting a union a set, given the sets we want to split it into -}
7397class Split s t st where
7498 -- where st ~ Union s t
@@ -89,8 +113,6 @@ instance {-# OVERLAPS #-} (Split s t st) => Split s (x ': t) (x ': st) where
89113 split (Ext x st) = let (s, t) = split st
90114 in (s, Ext x t)
91115
92−
93−
94116{-| Remove duplicates from a sorted list -}
95117type family Nub t where
96118 Nub '[] = '[]
@@ -126,10 +148,10 @@ class Subset s t where
126148instance Subset '[] '[] where
127149 subset xs = Empty
128150
129−instance Subset s t => Subset s (x ': t) where
151+instance {-# OVERLAPPABLE #-} Subset s t => Subset s (x ': t) where
130152 subset (Ext _ xs) = subset xs
131153
132−instance Subset s t => Subset (x ': s) (x ': t) where
154+instance {-# OVERLAPS #-} Subset s t => Subset (x ': s) (x ': t) where
133155 subset (Ext x xs) = Ext x (subset xs)
134156
135157
@@ -194,3 +216,21 @@ instance Conder False where
194216{-| Open-family for the ordering operation in the sort -}
195217
196218type family Cmp (a :: k) (b :: k) :: Ordering
219+
220+{-| Membership of an element in a set, with an acommanying
221+ value-level function that returns a bool -}
222+class Member a s where
223+ member :: Proxy a -> Set s -> Bool
224+
225+instance {-# OVERLAPS #-} Member a (a ': s) where
226+ member _ (Ext x _) = True
227+
228+instance {-# OVERLAPPABLE #-} Member a s => Member a (b ': s) where
229+ member a (Ext _ xs) = member a xs
230+
231+type family MemberP a s :: Bool where
232+ MemberP a '[] = False
233+ MemberP a (a ': s) = True
234+ MemberP a (b ': s) = MemberP a s
235+
236+type NonMember a s = MemberP a s ~ False
stack.yaml+1−1
@@ -1,7 +1,7 @@
11# For more information, see: https://github.com/commercialhaskell/stack/wiki/stack.yaml
22
33# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
4−resolver: lts-3.5
4+resolver: lts-12.7
55
66# Local packages, usually specified by relative directory name
77packages:
type-level-sets.cabal+31−25
@@ -1,39 +1,44 @@
11name: type-level-sets
2−version: 0.7
2+version: 0.8.9.0
33synopsis: Type-level sets and finite maps (with value-level counterparts)
4−description:
4+description:
55 This package provides type-level sets (no duplicates, sorted to provide a normal form) via 'Set' and type-level
66 finite maps via 'Map', with value-level counterparts.
77 .
8− Described in the paper \"Embedding effect systems in Haskell\" by Dominic Orchard
9− and Tomas Petricek <http://www.cl.cam.ac.uk/~dao29/publ/haskell14-effects.pdf> (Haskell Symposium, 2014). This version now uses Quicksort to normalise the representation.
8+ Described in the paper \"Embedding effect systems in Haskell\" by Dominic Orchard
9+ and Tomas Petricek <http://www.cl.cam.ac.uk/~dao29/publ/haskell14-effects.pdf> (Haskell Symposium, 2014). This version now uses Quicksort to normalise the representation.
1010 .
11− Here is a brief example for finite maps.:
11+ Here is a brief example for finite maps:
1212 .
1313 >
1414 > import Data.Type.Map
1515 >
16− > foo :: Map '["x" :-> Int, "z" :-> Int, "w" :-> Int]
17− > foo = Ext ((Var :: (Var "x")) :-> 2) $
18− > Ext ((Var :: (Var "z")) :-> 4) $
19− > Ext ((Var :: (Var "w")) :-> 5) $
20− > Empty
16+ > -- Specify how to combine duplicate key-value pairs for Int values
17+ > type instance Combine Int Int = Int
18+ > instance Combinable Int Int where
19+ > combine x y = x + y
20+ >
21+ > foo :: Map '["x" :-> Int, "z" :-> Bool, "w" :-> Int]
22+ > foo = Ext (Var :: (Var "x")) 2
23+ > $ Ext (Var :: (Var "z")) True
24+ > $ Ext (Var :: (Var "w")) 5
25+ > $ Empty
2126 >
2227 > bar :: Map '["y" :-> Int, "w" :-> Int]
23− > bar = Ext ((Var :: (Var "y")) :-> 3) $
24− > Ext ((Var :: (Var "w")) :-> 1) $
25− > Empty
26− >
27− > -- foobar :: Map '["w" :-> Int, "x" :-> Int, "y" :-> Int, "z" :-> Int]
28+ > bar = Ext (Var :: (Var "y")) 3
29+ > $ Ext (Var :: (Var "w")) 1
30+ > $ Empty
31+ >
32+ > -- foobar :: Map '["w" :-> Int, "x" :-> Int, "y" :-> Int, "z" :-> Bool]
2833 > foobar = foo `union` bar
2934 .
30− The 'Set' type for 'foobar' here shows the normalised form (sorted with no duplicates).
35+ The 'Map' type for 'foobar' here shows the normalised form (sorted with no duplicates).
3136 The type signatures is commented out as it can be infered. Running the example we get:
3237 .
33− > >>> foobar
34− > [(Var :-> 1), (Var :-> 2), (Var :-> 3), (Var :-> 4)]
38+ > >>> foobar
39+ > {w :-> 6, x :-> 2, y :-> 3, z :-> True}
3540 .
36− Thus, we see that the first value paired with the \"w\" variable is dropped.
41+ Thus, we see that the values for \"w\" are added together.
3742 For sets, here is an example:
3843 .
3944 > import GHC.TypeLits
@@ -43,7 +48,7 @@ description:
4348 > data Natural (a :: Nat) where
4449 > Z :: Natural 0
4550 > S :: Natural n -> Natural (n + 1)
46− >
51+ >
4752 > -- foo :: Set '[Natural 0, Natural 1, Natural 3]
4853 > foo = asSet $ Ext (S Z) (Ext (S (S (S Z))) (Ext Z Empty))
4954 >
@@ -58,15 +63,15 @@ description:
5863license: BSD3
5964license-file: LICENSE
6065category: Type System, Data Structures
61−copyright: 2013-16 University of Cambridge
66+copyright: 2013-18 University of Kent
6267author: Dominic Orchard
6368maintainer: Dominic Orchard
6469stability: experimental
6570build-type: Simple
6671cabal-version: >= 1.6
67−tested-with: GHC == 7.10.3
72+tested-with: GHC >= 8.2.2
6873
69−extra-source-files: example.hs
74+extra-source-files: example.hs, example2.hs, changelog.md
7075
7176
7277source-repository head
@@ -75,10 +80,11 @@ source-repository head
7580
7681library
7782 hs-source-dirs: src
83+ other-extensions: TypeInType
7884
7985
8086 exposed-modules: Data.Type.Set
8187 Data.Type.Map
82−
88+
8389 build-depends: base < 5,
84− ghc-prim
90+ ghc-prim