@@ -9,6 +9,8 @@ module TypeFun.Data.List
99 , Drop
1010 , Take
1111 , Delete
12+ , Remove
13+ , (:++:)
1214 -- * Elements lookup
1315 , IndexOf
1416 , IndexOfMay
@@ -33,10 +35,14 @@ module TypeFun.Data.List
3335 , UnionList
3436 , AppendUniq
3537 , Intersect
38+ , Substract
3639 -- * Uniqueness checking
3740 , ElementIsUniq
3841 , UniqElements
3942 , UniqElements'
43+ -- * Unsafe helpers
44+ , appendId
45+ , subListId
4046 ) where
4147
4248import Data.Type.Bool
@@ -45,6 +51,7 @@ import GHC.TypeLits
4551import TypeFun.Data.Eq
4652import TypeFun.Data.Maybe
4753import TypeFun.Data.Peano
54+import Unsafe.Coerce
4855
4956------------------------------------------------------------------------
5057-- NOTE: Errors type classes. These type classes are not in separate --
@@ -91,6 +98,23 @@ type family Delete (a :: k) (s :: [k]) :: [k] where
9198 Delete a (a ': as) = Delete a as
9299 Delete a (b ': as) = b ': (Delete a as)
93100
101+-- | Remove index from the list
102+type family Remove (i :: N) (a :: [k]) :: [k] where
103+ Remove i '[] = '[]
104+ Remove 'Z (a ': as) = as
105+ Remove ('S i) (a ': as) = a ': (Remove i as)
106+
107+type family (:++:) (a :: [k]) (b :: [k]) :: [k] where
108+ '[] :++: b = b
109+ (a ': as) :++: b = a ': (as :++: b)
110+
111+appendId
112+ :: forall proxy l r
113+ . proxy l
114+ -> (l ~ (l :++: '[]) => r)
115+ -> r
116+appendId = unsafeCoerce id
117+
94118type IndexOf a s = FromJust (IndexOfMay a s)
95119
96120type IndexOfMay a s = IndexOfMay' Z a s
@@ -144,6 +168,12 @@ type family SubList (a :: [k]) (b :: [k]) :: Constraint where
144168 SubList '[] bs = ()
145169 SubList (a ': as) bs = (Elem a bs, SubList as bs)
146170
171+subListId
172+ :: forall proxy l r
173+ . proxy l
174+ -> (SubList l l => r) -> r
175+subListId _ = unsafeCoerce id
176+
147177type family NotSubList (a :: [k]) (b :: [k]) :: Constraint where
148178 NotSubList '[] bs = ()
149179 NotSubList (a ': as) bs = (NotElem a bs, NotSubList as bs)
@@ -183,6 +213,12 @@ type family AppendUniq (a :: k) (s :: [k]) :: [k] where
183213-- taken from first list
184214type Intersect a b = (Indices (CatMaybes (IndicesOfMay a b)) b)
185215
216+-- | Removes from first list all elements occured in second
217+type family Substract (a :: [k]) (b :: [k]) :: [k] where
218+ Substract '[] b = '[]
219+ Substract a '[] = a
220+ Substract a (b ': bs) = Substract (Delete b a) bs
221+
186222-- | Checks that element 'a' occurs in a list just once
187223type ElementIsUniq a s = If (Equal (S Z) (Count a s))
188224 (() :: Constraint)