git.iko.soy/type-level-sets
on fd032fe help sign in
8 files changed+81−218
since splitsnapshots
unifiedsplit
README+21−42 changelog.md−5 example.hs+5−5 example2.hs−9 src/Data/Type/Map.hs+22−78 src/Data/Type/Set.hs+7−47 stack.yaml+1−1 type-level-sets.cabal+25−31
README+21−42
@@ -1,56 +1,35 @@
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,
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,
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, 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:
8+ {-# LANGUAGE DataKinds, TypeOperators #-}
329
33− *Main> foobar
34− {w :-> 6, x :-> 2, y :-> 3, z :-> True}
10+ import Data.Type.Set
3511
36−Thus, we see that values for 'w' are added.
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
3717
38− import GHC.TypeLits
39− import Data.Type.Set
40− type instance Cmp (Natural n) (Natural m) = CmpNat n m
18+ bar :: Set '["y" :-> Int, "w" :-> Int]
19+ bar = Ext ((Var :: (Var "y")) :-> 3) $
20+ Ext ((Var :: (Var "w")) :-> 1) $
21+ Empty
4122
42− data Natural (a :: Nat) where
43− Z :: Natural 0
44− S :: Natural n -> Natural (n + 1)
23+ -- foobar :: Set '["w" :-> Int, "x" :-> Int, "y" :-> Int, "z" :-> Int]
24+ foobar = foo `union` bar
4525
46− -- foo :: Set '[Natural 0, Natural 1, Natural 3]
47− foo = asSet $ Ext (S Z) (Ext (S (S (S Z))) (Ext Z Empty))
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:
4828
49− -- bar :: Set '[Natural 1, Natural 2]
50− bar = asSet $ Ext (S (S Z)) (Ext (S Z) (Ext (S Z) Empty))
29+ *Main> foobar
30+ {(Var :-> 1), (Var :-> 2), (Var :-> 3), (Var :-> 4)}
5131
52− -- foobar :: Set '[Natural 0, Natural 1, Natural 2, Natural 3]
53− foobar = foo `union` bar
32+Thus, we see that the first value paired with the "w" variable is dropped.
5433
5534
5635
changelog.mddeleted−5
@@ -1,5 +0,0 @@
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, TypeFamilies, MultiParamTypeClasses #-}
1+{-# LANGUAGE DataKinds, TypeOperators, KindSignatures, 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,5 +1,4 @@
11{-# LANGUAGE DataKinds, TypeOperators, TypeFamilies, GADTs, StandaloneDeriving #-}
2−{-# LANGUAGE FlexibleContexts #-}
32
43import GHC.TypeLits
54import Data.Type.Set
@@ -20,11 +19,3 @@ bar = asSet $ Ext (S (S Z)) (Ext (S Z) (Ext (S Z) Empty))
2019
2120-- foobar :: Set '[Natural 0, Natural 1, Natural 2, Natural 3]
2221foobar = 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+22−78
@@ -5,14 +5,13 @@ 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, IncoherentInstances #-}
8+ ConstraintKinds #-}
99
1010module Data.Type.Map (Mapping(..), Union, Unionable, union, Var(..), Map(..),
1111 Combine, Combinable(..), Cmp,
1212 Nubable, nub,
1313 Lookup, Member, (:\), Split, split,
14− IsMember, lookp, Updatable, update,
15− IsMap, AsMap, asMap,
14+ IsMap, AsMap, asMap,
1615 Submap, submap) where
1716
1817import GHC.TypeLits
@@ -46,17 +45,17 @@ type family Combine (a :: v) (b :: v) :: v
4645
4746{-| Delete elements from a map by key -}
4847type family (m :: [Mapping k v]) :\ (c :: k) :: [Mapping k v] where
49− '[] :\ k = '[]
50− ((k :-> v) ': m) :\ k = m :\ k
51− (kvp ': m) :\ k = kvp ': (m :\ k)
48+ '[] :\ k = '[]
49+ ((k :-> v) ': m) :\ k = m :\ k
50+ (kvp ': m) :\ k = kvp ': (m :\ k)
5251
53−{-| Type-level lookup of elements from a map -}
52+{-| Lookup elements from a map -}
5453type family Lookup (m :: [Mapping k v]) (c :: k) :: Maybe v where
5554 Lookup '[] k = Nothing
5655 Lookup ((k :-> v) ': m) k = Just v
5756 Lookup (kvp ': m) k = Lookup m k
5857
59−{-| Membership test as type function -}
58+{-| Membership test -}
6059type family Member (c :: k) (m :: [Mapping k v]) :: Bool where
6160 Member k '[] = False
6261 Member k ((k :-> v) ': m) = True
@@ -76,37 +75,6 @@ data Map (n :: [Mapping Symbol *]) where
7675 Empty :: Map '[]
7776 Ext :: Var k -> v -> Map m -> Map ((k :-> v) ': m)
7877
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−
11078{-| Predicate to check if in normalised map form -}
11179type IsMap s = (s ~ Nub (Sort s))
11280
@@ -121,7 +89,7 @@ instance Show (Map '[]) where
12189 show Empty = "{}"
12290
12391instance (KnownSymbol k, Show v, Show' (Map s)) => Show (Map ((k :-> v) ': s)) where
124− show (Ext k v s) = "{" ++ show k ++ " :-> " ++ show v ++ show' s ++ "}"
92+ show (Ext k v s) = "{" ++ show k ++ " :-> " ++ show v ++ (show' s) ++ "}"
12593
12694class Show' t where
12795 show' :: t -> String
@@ -130,25 +98,12 @@ instance Show' (Map '[]) where
13098instance (KnownSymbol k, Show v, Show' (Map s)) => Show' (Map ((k :-> v) ': s)) where
13199 show' (Ext k v s) = ", " ++ show k ++ " :-> " ++ show v ++ (show' s)
132100
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) -}
101+{-| Union of two finite maps -}
146102union :: (Unionable s t) => Map s -> Map t -> Map (Union s t)
147103union s t = nub (quicksort (append s t))
148104
149105type Unionable s t = (Nubable (Sort (s :++ t)), Sortable (s :++ t))
150106
151−{-| Append of two finite maps (non normalising) -}
152107append :: Map s -> Map t -> Map (s :++ t)
153108append Empty x = x
154109append (Ext k v xs) ys = Ext k v (append xs ys)
@@ -163,15 +118,11 @@ class Sortable xs where
163118instance Sortable '[] where
164119 quicksort Empty = Empty
165120
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))
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))
175126
176127{- Filter out the elements less-than or greater-than-or-equal to the pivot -}
177128class FilterV (f::Flag) k v xs where
@@ -180,19 +131,13 @@ class FilterV (f::Flag) k v xs where
180131instance FilterV f k v '[] where
181132 filterV _ k v Empty = Empty
182133
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)
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)
188137
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)
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)
196141
197142class Combinable t t' where
198143 combine :: t -> t' -> Combine t t'
@@ -206,14 +151,13 @@ instance Nubable '[] where
206151instance Nubable '[e] where
207152 nub (Ext k v Empty) = Ext k v Empty
208153
209−instance {-# OVERLAPPABLE #-}
154+instance {-# OVERLAPABLE #-}
210155 (Nub (e ': f ': s) ~ (e ': Nub (f ': s)),
211156 Nubable (f ': s)) => Nubable (e ': f ': s) where
212157 nub (Ext k v (Ext k' v' s)) = Ext k v (nub (Ext k' v' s))
213158
214159instance {-# OVERLAPS #-}
215− (Combinable v v', Nubable ((k :-> Combine v v') ': s))
216− => Nubable ((k :-> v) ': (k :-> v') ': s) where
160+ (Combinable v v', Nubable ((k :-> Combine v v') ': s)) => Nubable ((k :-> v) ': (k :-> v') ': s) where
217161 nub (Ext k v (Ext k' v' s)) = nub (Ext k (combine v v') s)
218162
219163
src/Data/Type/Set.hs+7−47
@@ -1,13 +1,12 @@
11{-# LANGUAGE GADTs, DataKinds, KindSignatures, TypeOperators, TypeFamilies,
22 MultiParamTypeClasses, FlexibleInstances, PolyKinds,
33 FlexibleContexts, UndecidableInstances, ConstraintKinds,
4− ScopedTypeVariables, TypeInType #-}
4+ ScopedTypeVariables #-}
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(..), remove, Remove, (:\),
10− Member(..), NonMember, MemberP(..)) where
9+ Delete(..), Proxy(..)) where
1110
1211import GHC.TypeLits
1312import Data.Type.Bool
@@ -16,7 +15,7 @@ import Data.Type.Equality
1615data Proxy (p :: k) = Proxy
1716
1817-- Value-level 'Set' representation, essentially a list
19−data Set (n :: [k]) where
18+data Set (n :: [*]) where
2019 {--| Construct an empty set -}
2120 Empty :: Set '[]
2221 {--| Extend a set with an element -}
@@ -35,10 +34,6 @@ instance Show' (Set '[]) where
3534instance (Show' (Set s), Show e) => Show' (Set (e ': s)) where
3635 show' (Ext e s) = ", " ++ show e ++ (show' s)
3736
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−
4237{-| At the type level, normalise the list form to the set form -}
4338type AsSet s = Nub (Sort s)
4439
@@ -74,25 +69,6 @@ append :: Set s -> Set t -> Set (s :++ t)
7469append Empty x = x
7570append (Ext e xs) ys = Ext e (append xs ys)
7671
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−
9672{-| Splitting a union a set, given the sets we want to split it into -}
9773class Split s t st where
9874 -- where st ~ Union s t
@@ -113,6 +89,8 @@ instance {-# OVERLAPS #-} (Split s t st) => Split s (x ': t) (x ': st) where
11389 split (Ext x st) = let (s, t) = split st
11490 in (s, Ext x t)
11591
92+
93+
11694{-| Remove duplicates from a sorted list -}
11795type family Nub t where
11896 Nub '[] = '[]
@@ -148,10 +126,10 @@ class Subset s t where
148126instance Subset '[] '[] where
149127 subset xs = Empty
150128
151−instance {-# OVERLAPPABLE #-} Subset s t => Subset s (x ': t) where
129+instance Subset s t => Subset s (x ': t) where
152130 subset (Ext _ xs) = subset xs
153131
154−instance {-# OVERLAPS #-} Subset s t => Subset (x ': s) (x ': t) where
132+instance Subset s t => Subset (x ': s) (x ': t) where
155133 subset (Ext x xs) = Ext x (subset xs)
156134
157135
@@ -216,21 +194,3 @@ instance Conder False where
216194{-| Open-family for the ordering operation in the sort -}
217195
218196type 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-12.7
4+resolver: lts-3.5
55
66# Local packages, usually specified by relative directory name
77packages:
type-level-sets.cabal+25−31
@@ -1,44 +1,39 @@
11name: type-level-sets
2−version: 0.8.9.0
2+version: 0.7
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− > -- 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
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
2621 >
2722 > bar :: Map '["y" :-> Int, "w" :-> 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]
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]
3328 > foobar = foo `union` bar
3429 .
35− The 'Map' type for 'foobar' here shows the normalised form (sorted with no duplicates).
30+ The 'Set' type for 'foobar' here shows the normalised form (sorted with no duplicates).
3631 The type signatures is commented out as it can be infered. Running the example we get:
3732 .
38− > >>> foobar
39− > {w :-> 6, x :-> 2, y :-> 3, z :-> True}
33+ > >>> foobar
34+ > [(Var :-> 1), (Var :-> 2), (Var :-> 3), (Var :-> 4)]
4035 .
41− Thus, we see that the values for \"w\" are added together.
36+ Thus, we see that the first value paired with the \"w\" variable is dropped.
4237 For sets, here is an example:
4338 .
4439 > import GHC.TypeLits
@@ -48,7 +43,7 @@ description:
4843 > data Natural (a :: Nat) where
4944 > Z :: Natural 0
5045 > S :: Natural n -> Natural (n + 1)
51− >
46+ >
5247 > -- foo :: Set '[Natural 0, Natural 1, Natural 3]
5348 > foo = asSet $ Ext (S Z) (Ext (S (S (S Z))) (Ext Z Empty))
5449 >
@@ -63,15 +58,15 @@ description:
6358license: BSD3
6459license-file: LICENSE
6560category: Type System, Data Structures
66−copyright: 2013-18 University of Kent
61+copyright: 2013-16 University of Cambridge
6762author: Dominic Orchard
6863maintainer: Dominic Orchard
6964stability: experimental
7065build-type: Simple
7166cabal-version: >= 1.6
72−tested-with: GHC >= 8.2.2
67+tested-with: GHC == 7.10.3
7368
74−extra-source-files: example.hs, example2.hs, changelog.md
69+extra-source-files: example.hs
7570
7671
7772source-repository head
@@ -80,11 +75,10 @@ source-repository head
8075
8176library
8277 hs-source-dirs: src
83− other-extensions: TypeInType
8478
8579
8680 exposed-modules: Data.Type.Set
8781 Data.Type.Map
88−
82+
8983 build-depends: base < 5,
90− ghc-prim
84+ ghc-prim