@@ -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
4+
5+module TypeFun.Data.List where
6+
7+import Data.Type.Bool
8+import GHC.Exts
9+import GHC.TypeLits
10+import TypeFun.Data.List.Internal
11+import TypeFun.Data.Maybe
12+
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)
17+
18+-- | Reverse of 'Elem'
19+type NotElem a s = JustToConstr (IndexOf a s)
20+ (ElementIsInList a s)
21+
22+
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
26+ SubList '[] bs = ()
27+ SubList (a ': as) bs = (Elem a bs, SubList as bs)
28+
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)
32+
33+
34+-- type family UniqElemsBool (a :: [k]) :: Bool where
35+-- UniqElemsBool
36+
37+type IndexOf a s = IndexOf' 0 a s
38+
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
43+
44+type IsPrefixOf a b = ( If (IsPrefixOfBool a b)
45+ (() :: Constraint)
46+ (ListIsNotPrefixOf a b)
47+ , SubList a b )
48+
49+type IsNotPrefixOf a b = If (IsPrefixOfBool a b)
50+ (ListIsPrefixOf a b)
51+ (() :: Constraint)
52+
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