dimensions-0.3.0.0: Safe type-level dimensionality for multidimensional data.

Copyright(c) Artem Chirkin
LicenseBSD3
Maintainerchirkin@arch.ethz.ch
Safe HaskellNone
LanguageHaskell2010

Numeric.Dimensions.List

Contents

Description

Provides type-level operations on lists.

  • Note for GHC 8.0 Due to GHC issue #13538 some complex type families could not be truly kind-polymorphic before GHC 8.2, thus I specialized them to work only on `[Nat]` and `[XNat]`.

Synopsis

Basic operations

type family (as :: [k]) ++ (bs :: [k]) :: [k] where ... infixr 5 Source #

List concatenation

Equations

'[] ++ bs = bs 
as ++ '[] = as 
(a :+ as) ++ bs = a :+ (as ++ bs) 

type (:+) a as = a ': as infixr 5 Source #

Synonym for a type-level cons (injective, since this is just a synonym for the list constructor)

type (+:) ns n = Snoc ns n infixl 5 Source #

Synonym for a type-level snoc (injective!)

type Empty = '[] Source #

Synonym for an empty type-level list

type Cons n ns = n :+ ns Source #

Prefix-style synonym for cons

type Snoc ns n = GetSnoc (DoSnoc ns n) Source #

Prefix-style synonym for snoc

type family Head (xs :: [k]) :: k where ... Source #

Equations

Head (x :+ xs) = x 
Head '[] = TypeError (Text "Head -- empty type-level list.") 

type family Tail (xs :: [k]) :: [k] where ... Source #

Equations

Tail (x :+ xs) = xs 
Tail '[] = TypeError (Text "Tail -- empty type-level list.") 

type family Init (xs :: [k]) :: [k] where ... Source #

Equations

Init '[x] = '[] 
Init (x :+ xs) = x :+ Init xs 
Init '[] = TypeError (Text "Init -- empty type-level list.") 

type family Last (xs :: [k]) :: k where ... Source #

Equations

Last '[x] = x 
Last (x :+ xs) = Last xs 
Last '[] = TypeError (Text "Last -- empty type-level list.") 

type Concat as bs = as ++ bs Source #

Prefix-style synonym for concatenation

type Reverse xs = Reversed (DoReverse xs) Source #

Reverse a type-level list (injective!)

type family Take (n :: Nat) (xs :: [k]) :: [k] where ... Source #

Equations

Take _ '[] = '[] 
Take 0 xs = '[] 
Take n (x :+ xs) = x :+ Take (n - 1) xs 

type family Drop (n :: Nat) (xs :: [k]) :: [k] where ... Source #

Equations

Drop _ '[] = '[] 
Drop 0 xs = xs 
Drop n (x :+ xs) = Drop (n - 1) xs 

Working with concatenations

type family Suffix (as :: [k]) (asbs :: [k]) :: [k] where ... Source #

Equations

Suffix '[] bs = bs 
Suffix as as = '[] 
Suffix (_ :+ as) (_ :+ asbs) = Suffix as asbs 

type family Prefix (bs :: [k]) (asbs :: [k]) :: [k] where ... Source #

Equations

Prefix '[] as = as 
Prefix bs bs = '[] 
Prefix bs asbs = Take (Length asbs - Length bs) asbs 

type family IsPrefix (as :: [k]) (asbs :: [k]) :: Bool where ... Source #

Equations

IsPrefix '[] _ = True 
IsPrefix (a :+ as) (a :+ asbs) = IsPrefix as asbs 
IsPrefix as as = True 
IsPrefix _ _ = False 

type family IsSuffix (as :: [k]) (asbs :: [k]) :: Bool where ... Source #

Equations

IsSuffix '[] _ = True 
IsSuffix bs bs = True 
IsSuffix bs (_ :+ sbs) = IsSuffix bs sbs 
IsSuffix _ _ = False 

Term level functions

class (asbs ~ Concat as bs, as ~ Prefix bs asbs, bs ~ Suffix as asbs, IsSuffix bs asbs ~ True, IsPrefix as asbs ~ True) => ConcatList as bs asbs | as bs -> asbs, as asbs -> bs, bs asbs -> as where Source #

Represent a triple of lists forming a relation `as ++ bs ~ asbs`

Minimal complete definition

tlPrefix, tlSuffix, tlConcat

Methods

tlPrefix :: ConcatEvidence as bs asbs -> Proxy as Source #

tlSuffix :: ConcatEvidence as bs asbs -> Proxy bs Source #

tlConcat :: ConcatEvidence as bs asbs -> Proxy asbs Source #

Instances

((~) [k] asbs (Concat k as bs), (~) [k] as (Prefix k bs asbs), (~) [k] bs (Suffix k as asbs), (~) Bool (IsSuffix k bs asbs) True, (~) Bool (IsPrefix k as asbs) True) => ConcatList k as bs asbs Source # 

Methods

tlPrefix :: ConcatEvidence as bs asbs asbs -> Proxy [as] bs Source #

tlSuffix :: ConcatEvidence as bs asbs asbs -> Proxy [as] asbs Source #

tlConcat :: ConcatEvidence as bs asbs asbs -> Proxy [as] asbs Source #

class FiniteList xs where Source #

Type-level list that is known to be finite. Basically, provides means to get its length and term-level rep (via TypeList)

Minimal complete definition

order, tList

Associated Types

type Length xs :: Nat Source #

Length of a type-level list at type level

Methods

order :: Int Source #

Length of a type-level list at term level

tList :: TypeList xs Source #

Get type-level constructed list

Instances

FiniteList k ([] k) Source # 

Associated Types

type Length ([] k) (xs :: [[] k]) :: Nat Source #

Methods

order :: Int Source #

tList :: TypeList [k] xs Source #

FiniteList k xs => FiniteList k ((:+) k x xs) Source # 

Associated Types

type Length ((:+) k x xs) (xs :: [(:+) k x xs]) :: Nat Source #

Methods

order :: Int Source #

tList :: TypeList ((k :+ x) xs) xs Source #

data TypeList xs where Source #

Type level list, used together with FiniteList typeclass

Constructors

TLEmpty :: TypeList '[] 
TLCons :: FiniteList xs => !(Proxy# x) -> !(TypeList xs) -> TypeList (x :+ xs) 

Instances

Show (TypeList k xs) Source # 

Methods

showsPrec :: Int -> TypeList k xs -> ShowS #

show :: TypeList k xs -> String #

showList :: [TypeList k xs] -> ShowS #

Term level inference of type-level functions

inferConcat :: forall as bs. ConcatEvidence as bs (as ++ bs) Source #

Any two type-level lists can be concatenated, so we just fool the compiler by unsafeCoercing proxy-like data type.

inferSuffix :: forall as asbs. IsPrefix as asbs ~ True => ConcatEvidence as (Suffix as asbs) asbs Source #

as being prefix of asbs is enough to infer some concatenation relations so we just fool the compiler by unsafeCoercing proxy-like data type.

inferPrefix :: forall bs asbs. IsSuffix bs asbs ~ True => ConcatEvidence (Prefix bs asbs) bs asbs Source #

bs being suffix of asbs is enough to infer some concatenation relations so we just fool the compiler by unsafeCoercing proxy-like data type.

type ConcatEvidence as bs asbs = Evidence (asbs ~ Concat as bs, as ~ Prefix bs asbs, bs ~ Suffix as asbs, IsSuffix bs asbs ~ True, IsPrefix as asbs ~ True) Source #

Pattern-matching on the constructor of this type brings an evidence that `as ++ bs ~ asbs`

type FiniteListEvidence xs = Evidence (FiniteList xs) Source #

Pattern-matching on the constructor of this type brings an evidence that the type-level parameter list is finite

inferKnownLength :: forall xs. FiniteList xs => Evidence (KnownDim (Length xs)) Source #

Length of a finite list is known and equal to order of the list

inferTailFiniteList :: forall xs. FiniteList xs => Maybe (Evidence (FiniteList (Tail xs))) Source #

Tail of the list is also known list

inferConcatFiniteList :: forall as bs. (FiniteList as, FiniteList bs) => Evidence (FiniteList (as ++ bs)) Source #

Infer that concatenation is also finite

inferPrefixFiniteList :: forall bs asbs. (IsSuffix bs asbs ~ True, FiniteList bs, FiniteList asbs) => Evidence (FiniteList (Prefix bs asbs)) Source #

Infer that prefix is also finite

inferSuffixFiniteList :: forall as asbs. (IsPrefix as asbs ~ True, FiniteList as, FiniteList asbs) => Evidence (FiniteList (Suffix as asbs)) Source #

Infer that suffix is also finite

inferSnocFiniteList :: forall xs z. FiniteList xs => Evidence (FiniteList (xs +: z)) Source #

Make snoc almost as good as cons

inferInitFiniteList :: forall xs. FiniteList xs => Maybe (Evidence (FiniteList (Init xs))) Source #

Init of the list is also known list

inferTakeNFiniteList :: forall n xs. (KnownDim n, FiniteList xs) => Evidence (FiniteList (Take n xs)) Source #

Take KnownDim of the list is also known list

inferDropNFiniteList :: forall n xs. (KnownDim n, FiniteList xs) => Evidence (FiniteList (Drop n xs)) Source #

Drop KnownDim of the list is also known list

inferReverseFiniteList :: forall xs. FiniteList xs => Evidence (FiniteList (Reverse xs)) Source #

Reverse of the list is also known list