{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Type.List
(
type (++), type (+:), type (:+)
, Empty, Cons, Snoc, Head
, Tail, Last, Init, Concat
, StripPrefix, StripSuffix
, Reverse, Take, Drop, Length
, All, Map, UnMap, Elem
, SnocList, ReverseList, ConcatList
, inferStripSuffix, inferStripPrefix, inferConcat
, inferTypeableCons
) where
import Data.Constraint (Constraint, Dict (..))
import Data.Type.List.Classes
import Data.Type.List.Families
import Data.Type.Lits
import Type.Reflection
type Empty = ('[] :: [k])
type Cons (a :: k) (as :: [k]) = a ': as
type family Take (n :: Nat) (xs :: [k]) :: [k] where
Take 0 _ = '[]
Take n (x ': xs) = x ': Take (n - 1) xs
Take _ '[] = '[]
type family Drop (n :: Nat) (xs :: [k]) :: [k] where
Drop 0 xs = xs
Drop n (_ ': xs) = Drop (n - 1) xs
Drop _ '[] = '[]
type family Length (xs :: [k]) :: Nat where
Length '[] = 0
Length (x ': xs) = Length xs + 1
type (a :: k) :+ (as :: [k]) = a ': as
infixr 5 :+
type (ns :: [k]) +: (n :: k) = Snoc ns n
infixl 6 +:
type (as :: [k]) ++ (bs :: [k]) = Concat as bs
infixr 5 ++
type family All (f :: k -> Constraint) (xs :: [k]) :: Constraint where
All _ '[] = ()
All f (x ': xs) = (f x, All f xs)
type family Map (f :: a -> b) (xs :: [a]) :: [b] where
Map f '[] = '[]
Map f (x ': xs) = f x ': Map f xs
type family UnMap (f :: a -> b) (xs :: [b]) :: [a] where
UnMap f '[] = '[]
UnMap f (f x ': ys) = x ': UnMap f ys
type family Elem (x :: k) (xs :: [k]) :: Constraint where
Elem x (x ': xs) = ()
Elem x (_ ': xs) = Elem x xs
inferTypeableCons :: forall ys x xs
. (Typeable ys, ys ~ (x ': xs))
=> Dict (Typeable x, Typeable xs)
inferTypeableCons :: Dict (Typeable x, Typeable xs)
inferTypeableCons = case Typeable ys => TypeRep ys
forall k (a :: k). Typeable a => TypeRep a
typeRep @ys of
App TypeRep a
_ TypeRep b
xRep `App` TypeRep b
xsRep
-> case ( TypeRep b -> (Typeable b => Dict (Typeable x)) -> Dict (Typeable x)
forall k (a :: k) r. TypeRep a -> (Typeable a => r) -> r
withTypeable TypeRep b
xRep (Typeable x => Dict (Typeable x)
forall (a :: Constraint). a => Dict a
Dict @(Typeable x))
, TypeRep b
-> (Typeable b => Dict (Typeable xs)) -> Dict (Typeable xs)
forall k (a :: k) r. TypeRep a -> (Typeable a => r) -> r
withTypeable TypeRep b
xsRep (Typeable xs => Dict (Typeable xs)
forall (a :: Constraint). a => Dict a
Dict @(Typeable xs))
) of
(Dict (Typeable x)
Dict, Dict (Typeable xs)
Dict) -> Dict (Typeable x, Typeable xs)
forall (a :: Constraint). a => Dict a
Dict