@@ -0,0 +1,57 @@
1+-- | Collection of type families on type lists. This module differs
2+-- from __Data.Singletons.Prelude.List__ because it polykinded and
3+-- works with __[*]__ as well
5+module TypeFun.Data.List where
10+import TypeFun.Data.List.Internal
11+import TypeFun.Data.Maybe
13+-- | Generates unresolvable constraint if fists element is not
14+-- contained inside of second
15+type Elem a s = NothingToConstr (IndexOf a s)
16+ (ElementNotFoundInList a s)
18+-- | Reverse of 'Elem'
19+type NotElem a s = JustToConstr (IndexOf a s)
20+ (ElementIsInList a s)
23+-- | Constanints that first argument is a sublist of second. Reduces
24+-- to __(Elem a1 b, Elem a2 b, Elem a3 b, ...)__
25+type family SubList (a :: [k]) (b :: [k]) :: Constraint where
27+ SubList (a ': as) bs = (Elem a bs, SubList as bs)
29+-- type family SubListBool (a :: [k]) (b :: [k]) :: Bool where
30+-- SubListBool '[] bs = 'True
31+-- SubListBool (a ': as) bs = (ElemBool a bs) && (SubListBool as bs)
34+-- type family UniqElemsBool (a :: [k]) :: Bool where
37+type IndexOf a s = IndexOf' 0 a s
39+type family IndexOf' (acc :: Nat) (a :: k) (s :: [k]) :: Maybe Nat where
40+ IndexOf' acc a '[] = 'Nothing
41+ IndexOf' acc a (a ': as) = 'Just acc
42+ IndexOf' acc a (b ': as) = IndexOf' (acc + 1) a as
44+type IsPrefixOf a b = ( If (IsPrefixOfBool a b)
46+ (ListIsNotPrefixOf a b)
49+type IsNotPrefixOf a b = If (IsPrefixOfBool a b)
53+-- | First argument is prefix of second
54+type family IsPrefixOfBool (a :: [k]) (b :: [k]) :: Bool where
55+ IsPrefixOfBool '[] b = 'True
56+ IsPrefixOfBool (a ': as) (a ': bs) = IsPrefixOfBool as bs
57+ IsPrefixOfBool as bs = 'False