on master help sign in
add Union and intersection
commit7c20294c89fe0f93e2789c57adb14cbd0ba5de25 authorAleksey Uimanov <s9gf4ult@gmail.com> dateSun 25 Oct 2015, 20:54 (11 years ago) parent1392072
2 files changed+34−1
src/TypeFun/Data/List.hs+29−1 src/TypeFun/Data/Maybe.hs+5
src/TypeFun/Data/List.hs+29−1
@@ -12,7 +12,9 @@ module TypeFun.Data.List
1212 -- * Elements lookup
1313 , IndexOf
1414 , IndexOf'
15+ , IndicesOf
1516 , Index
17+ , Indices
1618 , Elem
1719 , NotElem
1820 , Count
@@ -22,6 +24,9 @@ module TypeFun.Data.List
2224 , IsPrefixOf
2325 , IsNotPrefixOf
2426 , IsPrefixOfBool
27+ , Union
28+ , AppendUniq
29+ , Intersect
2530 -- * Uniqueness checking
2631 , ElementIsUniq
2732 , UniqElements
@@ -85,11 +90,19 @@ type family IndexOf' (acc :: N) (a :: k) (s :: [k]) :: Maybe N where
8590 IndexOf' acc a (a ': as) = 'Just acc
8691 IndexOf' acc a (b ': as) = IndexOf' (S acc) a as
8792
93+type family IndicesOf (a :: [k]) (b :: [k]) :: [Maybe N] where
94+ IndicesOf '[] bs = '[]
95+ IndicesOf (a ': as) bs = (IndexOf a bs) ': (IndicesOf as bs)
96+
8897type family Index (idx :: N) (s :: [k]) :: Maybe k where
8998 Index idx '[] = 'Nothing
9099 Index Z (a ': as) = 'Just a
91100 Index (S idx) (a ': as) = Index idx as
92101
102+type family Indices (idxs :: [N]) (a :: [k]) :: [Maybe k] where
103+ Indices '[] as = '[]
104+ Indices (i ': idxs) as = (Index i as) ': (Indices idxs as)
105+
93106
94107-- | Generates unresolvable constraint if fists element is not
95108-- contained inside of second
@@ -131,12 +144,27 @@ type family IsPrefixOfBool (a :: [k]) (b :: [k]) :: Bool where
131144 IsPrefixOfBool (a ': as) (a ': bs) = IsPrefixOfBool as bs
132145 IsPrefixOfBool as bs = 'False
133146
147+-- | Appends elements from first list to second if they are not
148+-- presented in.
149+type family Union (a :: [k]) (b :: [k]) :: [k] where
150+ Union '[] bs = bs
151+ Union (a ': as) bs = Union as (AppendUniq a bs)
152+
153+-- | Append element to list if element is not already presented in
154+type family AppendUniq (a :: k) (s :: [k]) :: [k] where
155+ AppendUniq a (a ': bs) = a ': bs
156+ AppendUniq a (b ': bs) = b ': (AppendUniq a bs)
157+ AppendUniq a '[] = '[a]
158+
159+-- | Calculates intersection between two lists. Order of elements is
160+-- taken from first list
161+type Intersect a b = (CatMaybes (Indices (CatMaybes (IndicesOf a b)) b))
162+
134163-- | Checks that element 'a' occurs in a list just once
135164type ElementIsUniq a s = If (Equal (S Z) (Count a s))
136165 (() :: Constraint)
137166 (ElementIsNotUniqInList a s)
138167
139−
140168-- | Checks that all elements in list are unique
141169type UniqElements a = UniqElements' a a
142170
src/TypeFun/Data/Maybe.hs+5
@@ -16,3 +16,8 @@ type family NothingToConstr (a :: Maybe k) (c :: Constraint) :: Constraint where
1616type family JustToConstr (a :: Maybe k) (c :: Constraint) :: Constraint where
1717 JustToConstr 'Nothing c = ()
1818 JustToConstr ('Just a) c = c
19+
20+type family CatMaybes (l :: [Maybe k]) :: [k] where
21+ CatMaybes '[] = '[]
22+ CatMaybes (('Just a) ': as) = a ': (CatMaybes as)
23+ CatMaybes ('Nothing ': as) = CatMaybes as