module Data.Diverse.TypeLevel.Internal where
import Data.Kind
import GHC.TypeLits
type family PositionOfImpl (i :: Nat) (x :: k) (xs :: [k]) :: Nat where
PositionOfImpl i x (x ': xs) = i + 1
PositionOfImpl i y (x ': xs) = PositionOfImpl (i + 1) y xs
PositionOfImpl i x '[] = 0
type family IndexOfImpl (ctx :: [k]) (x :: k) (xs :: [k]) :: Nat where
IndexOfImpl ctx x (x ': xs) = 0
IndexOfImpl ctx y (x ': xs) = 1 + IndexOfImpl ctx y xs
IndexOfImpl ctx y '[] = TypeError ('Text "IndexOf error: ‘"
':<>: 'ShowType y
':<>: 'Text "’"
':<>: 'Text " is not a member of "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
type family NubImpl (ctx :: [k]) (y :: k) (ys :: [k]) :: [k] where
NubImpl '[] y '[] = y ': '[]
NubImpl '[] y (y ': xs) = '[]
NubImpl (x ': xs) y '[] = y ': NubImpl xs x xs
NubImpl (x ': xs) y (y ': ys) = NubImpl xs x xs
NubImpl ctx y (x ': xs) = NubImpl ctx y xs
type family IsUniqueImpl (ctx :: [k]) (y :: k) (xs :: [k]) :: Constraint where
IsUniqueImpl ctx y '[] = ()
IsUniqueImpl ctx x (x ': xs) = TypeError ('Text "Not unique error: ‘"
':<>: 'ShowType x
':<>: 'Text "’"
':<>: 'Text " is a duplicate in "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
IsUniqueImpl ctx y (x ': xs) = (IsUniqueImpl ctx y xs)
type family IsUniqueLabelImpl (ctx :: [k]) (l :: k2) (xs :: [k]) :: Constraint where
IsUniqueLabelImpl ctx y '[] = ()
IsUniqueLabelImpl ctx l (tagged l x ': xs) = TypeError ('Text "Not unique label error: ‘"
':<>: 'ShowType l
':<>: 'Text "’"
':<>: 'Text " is a duplicate in "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
IsUniqueLabelImpl ctx l (x ': xs) = (IsUniqueLabelImpl ctx l xs)
type family IsDistinctImpl (ctx :: [k]) (xs :: [k]) :: Constraint where
IsDistinctImpl ctx '[] = ()
IsDistinctImpl ctx (x ': xs) = (IsUniqueImpl ctx x xs, IsDistinctImpl ctx xs)
type family UniqueImpl (ctx :: [k]) (x :: k) (xs :: [k]) :: Constraint where
UniqueImpl ctx x '[] = ()
UniqueImpl ctx x (x ': xs) = IsUniqueImpl ctx x xs
UniqueImpl ctx x (y ': xs) = UniqueImpl ctx x xs
type family UniqueLabelImpl (ctx :: [k]) (l :: k1) (xs :: [k]) :: Constraint where
UniqueLabelImpl ctx l '[] = ()
UniqueLabelImpl ctx l (tagged l x ': xs) = IsUniqueLabelImpl ctx l xs
UniqueLabelImpl ctx l (y ': xs) = UniqueLabelImpl ctx l xs
type family KindAtIndexImpl (orig :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: k where
KindAtIndexImpl i ctx 0 '[] = TypeError ('Text "KindAtIndex error: Index ‘"
':<>: 'ShowType i
':<>: 'Text "’"
':<>: 'Text " is out of bounds of "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
KindAtIndexImpl i ctx 0 (x ': xs) = x
KindAtIndexImpl i ctx n (x ': xs) = KindAtIndexImpl i ctx (n 1) xs
type family KindAtLabelImpl (l :: k1) (ctx :: [k]) (xs :: [k]) :: k where
KindAtLabelImpl l ctx '[] = TypeError ('Text "KindAtLabel error: Label ‘"
':<>: 'ShowType l
':<>: 'Text "’"
':<>: 'Text " is not found in "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
KindAtLabelImpl l ctx (tagged l x ': xs) = tagged l x
KindAtLabelImpl l ctx (x ': xs) = KindAtLabelImpl l ctx xs
type family SameLengthImpl (ctx :: [k1]) (cty :: [k2]) (xs :: [k1]) (yx :: [k2]) :: Constraint where
SameLengthImpl as bs '[] '[] = ()
SameLengthImpl as bs (x ': xs) (y ': ys) = SameLengthImpl as bs xs ys
SameLengthImpl as bs xs ys = TypeError ('Text "SameLength error: ‘"
':<>: 'ShowType as
':<>: 'Text "’"
':<>: 'Text " is not the same length as "
':<>: 'Text "‘"
':<>: 'ShowType bs
':<>: 'Text "’")
type family RemoveIndexImpl (i :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: [k] where
RemoveIndexImpl i ctx n '[] = TypeError ('Text "RemoveIndex error: Index ‘"
':<>: 'ShowType i
':<>: 'Text "’"
':<>: 'Text " is out of bounds of "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
RemoveIndexImpl i ctx 0 (x ': xs) = xs
RemoveIndexImpl i ctx n (x ': xs) = x ': RemoveIndexImpl i ctx (n 1) xs
type family ReplaceIndexImpl (i :: Nat) (ctx :: [k]) (n :: Nat) (y :: k) (xs :: [k]) :: [k] where
ReplaceIndexImpl i ctx n y '[] = TypeError ('Text "ReplaceIndex error: Index ‘"
':<>: 'ShowType i
':<>: 'Text "’"
':<>: 'Text " is out of bounds of "
':<>: 'Text "‘"
':<>: 'ShowType ctx
':<>: 'Text "’")
ReplaceIndexImpl i ctx 0 y (x ': xs) = y ': xs
ReplaceIndexImpl i ctx n y (x ': xs) = x ': ReplaceIndexImpl i ctx (n 1) y xs
type family ReplaceImpl (x :: k) (y :: k) (xs :: [k]) :: [k] where
ReplaceImpl x y '[] = '[]
ReplaceImpl x y (x ': xs) = y ': xs
ReplaceImpl x y (z ': xs) = z ': ReplaceImpl x y xs
type family ReplacesImpl (xs' :: [k]) (ys' :: [k]) (xs :: [k]) (ys :: [k]) (zs :: [k]) :: [k] where
ReplacesImpl xs' ys' xs ys '[] = '[]
ReplacesImpl xs' ys' '[] '[] (z ': zs) = z ': ReplacesImpl xs' ys' xs' ys' zs
ReplacesImpl xs' ys' (x ': xs) (y ': ys) (x ': zs) = y ': ReplacesImpl xs' ys' xs' ys' zs
ReplacesImpl xs' ys' (x ': xs) (y ': ys) (z ': zs) = ReplacesImpl xs' ys' xs ys (z ': zs)
ReplacesImpl xs' ys' xs ys zs = TypeError ('Text "Replaces error: ‘"
':<>: 'ShowType xs'
':<>: 'Text "’"
':<>: 'Text " must be the same size as "
':<>: 'Text "‘"
':<>: 'ShowType ys'
':<>: 'Text "’")
type family ReplaceIfIndex (ns :: [Nat]) (ys :: [k]) (i :: Nat) (x :: k) :: k where
ReplaceIfIndex '[] ys i x = x
ReplaceIfIndex ns '[] i x = x
ReplaceIfIndex (n ': ns) (y ': ys) n x = y
ReplaceIfIndex (n ': ns) (y ': ys) i x = ReplaceIfIndex ns ys i x
type family ReplacesIndexImpl (i :: Nat) (ns :: [Nat]) (ys :: [k]) (xs :: [k]) :: [k] where
ReplacesIndexImpl i ns ys '[] = '[]
ReplacesIndexImpl i '[] '[] xs = xs
ReplacesIndexImpl i ns ys (x ': xs) = ReplaceIfIndex ns ys i x ': ReplacesIndexImpl (i + 1) ns ys xs
ReplacesIndexImpl i ns ys xs = TypeError ('Text "ReplacesIndex error: ‘"
':<>: 'ShowType ns
':<>: 'Text "’"
':<>: 'Text " must be the same size as "
':<>: 'Text "‘"
':<>: 'ShowType ys
':<>: 'Text "’")
type family ZipImpl (xs' :: [k]) (ys' :: [k]) (xs :: [k]) (ys :: [k]) :: [k] where
ZipImpl xs' ys' '[] '[] = '[]
ZipImpl xs' ys' (x ': xs) (y ': ys) = (x, y) ': ZipImpl xs' ys' xs ys
ZipImpl xs' ys' xs ys = TypeError ('Text "Zip error: ‘"
':<>: 'ShowType xs'
':<>: 'Text "’"
':<>: 'Text " must be the same size as "
':<>: 'Text "‘"
':<>: 'ShowType ys'
':<>: 'Text "’")