-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Safe type-level dimensionality for multidimensional data. -- -- Safe type-level dimensionality for multidimensional data. @package dimensions @version 1.0.0.0 -- | Construct type-level evidence at runtime module Numeric.Type.Evidence -- | Bring an instance of certain class or constaint satisfaction evidence -- into scope. data Evidence :: Constraint -> Type [E] :: a => Evidence a -- | Pattern match agains evidence to get constraints info withEvidence :: Evidence a -> (a => r) -> r -- | Combine evidence sumEvs :: Evidence a -> Evidence b -> Evidence (a, b) -- | Combine evidence (+!+) :: Evidence a -> Evidence b -> Evidence (a, b) infixl 4 +!+ -- | Same as Evidence, but allows to separate constraint function -- from the type it is applied to. data Evidence' :: (k -> Constraint) -> k -> Type [E'] :: c a => Evidence' c a toEvidence :: Evidence' c a -> Evidence (c a) toEvidence' :: Evidence (c a) -> Evidence' c a -- | This module is based on TypeLits and re-exports its -- functionality. It provides KnownDim class that is similar to -- KnownNat, but keeps Ints instead of Integers; -- Also it provides Dim data family serving as a customized -- Proxy type and a singleton suitable for recovering an -- instance of the KnownDim class. A set of utility functions -- provide inference functionality, so that KnownDim can be -- preserved over some type-level operations. module Numeric.Dim -- | Either known or unknown at compile-time natural number data XNat XN :: Nat -> XNat N :: Nat -> XNat -- | Unknown natural number, known to be not smaller than the given Nat type XN (n :: Nat) = 'XN n -- | Known natural number type N (n :: Nat) = 'N n -- | Find out whether XNat is of known or constrained type. data XNatType :: XNat -> Type -- | Given XNat is known [Nt] :: XNatType ( 'N n) -- | Given XNat is constrained unknown [XNt] :: XNatType ( 'XN m) -- | Singleton type to store type-level dimension value. -- -- On the one hand, it can be used to let type-inference system know -- relations between type-level naturals. On the other hand, this is just -- a newtype wrapper on the Word type. -- -- Usually, the type parameter of Dim is either Nat or -- XNat. If dimensionality of your data is known in advance, use -- Nat; if you know the size of some dimensions, but do not know -- the size of others, use XNats to represent them. data Dim (x :: k) -- | Same as SomeNat type SomeDim = Dim ( 'XN 0) -- | This class provides the Dim associated with a type-level -- natural. class KnownDim (n :: k) -- | Get value of type-level dim at runtime. -- -- Note, this function is supposed to be used with -- TypeApplications, and the KnownDim class has varying -- kind of the parameter; thus, the function has two type paremeters -- (kind and type of n). For example, you can type: -- --
-- >>> :set -XTypeApplications -- -- >>> :set -XDataKinds -- -- >>> :t dim @Nat @3 -- dim @Nat @3 :: Dim 3 ---- --
-- >>> :set -XTypeOperators -- -- >>> :t dim @_ @(13 - 6) -- dim @_ @(13 - 6) :: Dim 7 ---- --
-- >>> :t dim @_ @(N 17) -- dim @_ @(N 17) :: Dim (N 17) --dim :: KnownDim n => Dim n -- | Find out the type of XNat constructor class KnownXNatType (n :: XNat) -- | Pattern-match against this to out the type of XNat constructor xNatType :: KnownXNatType n => XNatType n -- | Similar to natVal from TypeLits, but returns -- Word. dimVal :: Dim (x :: k) -> Word -- | Similar to natVal from TypeLits, but returns -- Word. dimVal' :: forall n. KnownDim n => Word -- | Similar to someNatVal from TypeLits. someDimVal :: Word -> SomeDim -- | We either get evidence that this function was instantiated with the -- same type-level numbers, or Nothing. -- -- Note, this function works on Nat-indexed dimensions only, -- because Dim (XN x) does not have runtime evidence to infer -- x and `KnownDim x` does not imply `KnownDim (XN x)`. sameDim :: forall (x :: Nat) (y :: Nat). Dim x -> Dim y -> Maybe (Evidence (x ~ y)) -- | We either get evidence that this function was instantiated with the -- same type-level numbers, or Nothing. sameDim' :: forall (x :: Nat) (y :: Nat) p q. (KnownDim x, KnownDim y) => p x -> q y -> Maybe (Evidence (x ~ y)) -- | Ordering of dimension values. compareDim :: Dim a -> Dim b -> Ordering -- | Ordering of dimension values. compareDim' :: forall a b p q. (KnownDim a, KnownDim b) => p a -> q b -> Ordering -- | Change the minimum allowed size of a Dim (XN x), while -- testing if the value inside satisfies it. constrain :: forall (m :: Nat) x. KnownDim m => Dim x -> Maybe (Dim (XN m)) -- | constrain with explicitly-passed constraining Dim to -- avoid AllowAmbiguousTypes. constrainBy :: forall m x. Dim m -> Dim x -> Maybe (Dim (XN m)) -- | Decrease minimum allowed size of a Dim (XN x). relax :: forall (m :: Nat) (n :: Nat). (MinDim m n) => Dim (XN n) -> Dim (XN m) plusDim :: Dim n -> Dim m -> Dim (n + m) minusDim :: MinDim m n => Dim n -> Dim m -> Dim (n - m) minusDimM :: Dim n -> Dim m -> Maybe (Dim (n - m)) timesDim :: Dim n -> Dim m -> Dim ((*) n m) powerDim :: Dim n -> Dim m -> Dim ((^) n m) -- | (Kind) This is the kind of type-level natural numbers. data Nat :: * -- | Comparison of type-level naturals, as a function. -- | Addition of type-level naturals. -- | Subtraction of type-level naturals. -- | Multiplication of type-level naturals. -- | Exponentiation of type-level naturals. -- | Friendly error message if `m <= n` constraint is not satisfied. Use -- this type family instead of (<=) if possible or try -- inferDimLE function as the last resort. -- | Constraints given by an XNat type on possible values of a Nat hidden -- inside. -- | MinDim implies (<=), but this fact is not so -- clear to GHC. This function assures the type system that the relation -- takes place. inferDimLE :: forall m n. MinDim m n => Evidence (m <= n) -- | Figure out whether the type-level dimension is Nat or -- XNat. Useful for generalized inference functions. class KnownDimKind k dimKind :: KnownDimKind k => DimKind k -- | GADT to support KnownDimKind type class. Match against its -- constructors to know if k is Nat or XNat data DimKind :: Type -> Type -- | Working on Nat. [DimNat] :: DimKind Nat -- | Working on XNat. [DimXNat] :: DimKind XNat instance Numeric.Dim.KnownDimKind GHC.Types.Nat instance Numeric.Dim.KnownDimKind Numeric.Dim.XNat instance Numeric.Dim.KnownXNatType ('Numeric.Dim.N n) instance Numeric.Dim.KnownXNatType ('Numeric.Dim.XN n) instance GHC.TypeNats.KnownNat n => Numeric.Dim.KnownDim n instance Numeric.Dim.KnownDim 0 instance Numeric.Dim.KnownDim 1 instance Numeric.Dim.KnownDim 2 instance Numeric.Dim.KnownDim 3 instance Numeric.Dim.KnownDim 4 instance Numeric.Dim.KnownDim 5 instance Numeric.Dim.KnownDim 6 instance Numeric.Dim.KnownDim 7 instance Numeric.Dim.KnownDim 8 instance Numeric.Dim.KnownDim 9 instance Numeric.Dim.KnownDim 10 instance Numeric.Dim.KnownDim 11 instance Numeric.Dim.KnownDim 12 instance Numeric.Dim.KnownDim 13 instance Numeric.Dim.KnownDim 14 instance Numeric.Dim.KnownDim 15 instance Numeric.Dim.KnownDim 16 instance Numeric.Dim.KnownDim 17 instance Numeric.Dim.KnownDim 18 instance Numeric.Dim.KnownDim 19 instance Numeric.Dim.KnownDim 20 instance Numeric.Dim.KnownDim n => Numeric.Dim.KnownDim ('Numeric.Dim.N n) instance Numeric.Dim.KnownDim m => GHC.Read.Read (Numeric.Dim.Dim ('Numeric.Dim.XN m)) instance GHC.Classes.Eq (Numeric.Dim.Dim n) instance GHC.Classes.Eq (Numeric.Dim.Dim x) instance GHC.Classes.Ord (Numeric.Dim.Dim n) instance GHC.Classes.Ord (Numeric.Dim.Dim x) instance forall k (x :: k). GHC.Show.Show (Numeric.Dim.Dim x) -- | Provides type-level operations on lists. module Numeric.Type.List -- | List concatenation -- | Synonym for a type-level snoc (injective!) type (ns :: [k]) +: (n :: k) = Snoc ns n -- | Synonym for a type-level cons (injective, since this is just a synonym -- for the list constructor) type (a :: k) :+ (as :: [k]) = a : as -- | Synonym for an empty type-level list type Empty = '[] -- | Prefix-style synonym for cons type Cons (n :: k) (ns :: [k]) = n :+ ns -- | Prefix-style synonym for snoc type Snoc (ns :: [k]) (n :: k) = GetSnoc k (DoSnoc k ns n) -- | Prefix-style synonym for concatenation type Concat (as :: [k]) (bs :: [k]) = as ++ bs -- | Reverse a type-level list (injective!) type Reverse (xs :: [k]) = Reversed k (DoReverse k xs) -- | Represent a triple of lists forming a relation `as ++ bs ~ asbs` class (asbs ~ Concat as bs, as ~ Prefix bs asbs, bs ~ Suffix as asbs, IsSuffix bs asbs ~ 'True, IsPrefix as asbs ~ 'True) => ConcatList (as :: [k]) (bs :: [k]) (asbs :: [k]) | as bs -> asbs, as asbs -> bs, bs asbs -> as instance forall k (asbs :: [k]) (as :: [k]) (bs :: [k]). (asbs ~ Numeric.Type.List.Concat as bs, as ~ Numeric.Type.List.Prefix bs asbs, bs ~ Numeric.Type.List.Suffix as asbs, Numeric.Type.List.IsSuffix bs asbs ~ 'GHC.Types.True, Numeric.Type.List.IsPrefix as asbs ~ 'GHC.Types.True) => Numeric.Type.List.ConcatList as bs asbs -- | Provide a type-indexed heterogeneous list type TypedList. -- Behind the facade, TypedList is just a plain list of haskell -- pointers. It is used to represent dimension lists, indices, and just -- flexible tuples. -- -- Most of type-level functionality is implemented using GADT-like -- pattern synonyms. Import this module qualified to use list-like -- functionality. module Numeric.TypedList -- | Type-indexed list data TypedList (f :: (k -> Type)) (xs :: [k]) -- | Representable type lists. Allows getting type information about list -- structure at runtime. class RepresentableList (xs :: [k]) -- | Get type-level constructed list tList :: RepresentableList xs => TypeList xs -- | A list of type proxies type TypeList (xs :: [k]) = TypedList Proxy xs -- | Get a constructible TypeList from any other TypedList; -- Pattern matching agains the result brings RepresentableList -- constraint into the scope: -- --
-- case types ts of TypeList -> ... --types :: TypedList f xs -> TypeList xs order :: TypedList f xs -> Dim (Length xs) order' :: forall xs. RepresentableList xs => Dim (Length xs) cons :: f x -> TypedList f xs -> TypedList f (x :+ xs) snoc :: TypedList f xs -> f x -> TypedList f (xs +: x) reverse :: TypedList f xs -> TypedList f (Reverse xs) take :: Dim n -> TypedList f xs -> TypedList f (Take n xs) drop :: Dim n -> TypedList f xs -> TypedList f (Drop n xs) head :: TypedList f xs -> f (Head xs) tail :: TypedList f xs -> TypedList f (Tail xs) last :: TypedList f xs -> f (Last xs) init :: TypedList f xs -> TypedList f (Init xs) splitAt :: Dim n -> TypedList f xs -> (TypedList f (Take n xs), TypedList f (Drop n xs)) concat :: TypedList f xs -> TypedList f ys -> TypedList f (xs ++ ys) length :: TypedList f xs -> Dim (Length xs) -- | Map a function over contents of a typed list map :: (forall a. f a -> g a) -> TypedList f xs -> TypedList g xs instance Numeric.TypedList.RepresentableList '[] instance forall k (xs :: [k]) (x :: k). Numeric.TypedList.RepresentableList xs => Numeric.TypedList.RepresentableList (x : xs) module Numeric.Tuple.Strict -- | This is an almost complete copy of Identity by (c) Andy Gill -- 2001. newtype Id a Id :: a -> Id a [runId] :: Id a -> a -- | A tuple indexed by a list of types type Tuple (xs :: [Type]) = TypedList Id xs -- | Type-indexed list data TypedList (f :: (k -> Type)) (xs :: [k]) -- | Grow a tuple on the left O(1). (*$) :: x -> Tuple xs -> Tuple (x :+ xs) infixr 5 *$ -- | Grow a tuple on the right. Note, it traverses an element list inside -- O(n). ($*) :: Tuple xs -> x -> Tuple (xs +: x) infixl 5 $* -- | Grow a tuple on the left while evaluating arguments to WHNF O(1). (*!) :: x -> Tuple xs -> Tuple (x :+ xs) infixr 5 *! -- | Grow a tuple on the right while evaluating arguments to WHNF. Note, it -- traverses an element list inside O(n). (!*) :: Tuple xs -> x -> Tuple (xs +: x) infixl 5 !* instance Data.Traversable.Traversable Numeric.Tuple.Strict.Id instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Numeric.Tuple.Strict.Id a) instance Data.Semigroup.Semigroup a => Data.Semigroup.Semigroup (Numeric.Tuple.Strict.Id a) instance GHC.Float.RealFloat a => GHC.Float.RealFloat (Numeric.Tuple.Strict.Id a) instance GHC.Real.RealFrac a => GHC.Real.RealFrac (Numeric.Tuple.Strict.Id a) instance GHC.Real.Real a => GHC.Real.Real (Numeric.Tuple.Strict.Id a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Numeric.Tuple.Strict.Id a) instance GHC.Num.Num a => GHC.Num.Num (Numeric.Tuple.Strict.Id a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Numeric.Tuple.Strict.Id a) instance GHC.Arr.Ix a => GHC.Arr.Ix (Numeric.Tuple.Strict.Id a) instance Data.String.IsString a => Data.String.IsString (Numeric.Tuple.Strict.Id a) instance GHC.Real.Integral a => GHC.Real.Integral (Numeric.Tuple.Strict.Id a) instance GHC.Generics.Generic1 Numeric.Tuple.Strict.Id instance GHC.Generics.Generic (Numeric.Tuple.Strict.Id a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.Tuple.Strict.Id a) instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.Tuple.Strict.Id a) instance Data.Bits.FiniteBits a => Data.Bits.FiniteBits (Numeric.Tuple.Strict.Id a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.Tuple.Strict.Id a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Numeric.Tuple.Strict.Id a) instance Data.Data.Data a => Data.Data.Data (Numeric.Tuple.Strict.Id a) instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.Tuple.Strict.Id a) instance Data.Bits.Bits a => Data.Bits.Bits (Numeric.Tuple.Strict.Id a) instance Numeric.Type.List.All Data.Semigroup.Semigroup xs => Data.Semigroup.Semigroup (Numeric.Tuple.Strict.Tuple xs) instance (Data.Semigroup.Semigroup (Numeric.Tuple.Strict.Tuple xs), Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All GHC.Base.Monoid xs) => GHC.Base.Monoid (Numeric.Tuple.Strict.Tuple xs) instance (Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All GHC.Enum.Bounded xs) => GHC.Enum.Bounded (Numeric.Tuple.Strict.Tuple xs) instance Numeric.Type.List.All GHC.Classes.Eq xs => GHC.Classes.Eq (Numeric.Tuple.Strict.Tuple xs) instance (Numeric.Type.List.All GHC.Classes.Eq xs, Numeric.Type.List.All GHC.Classes.Ord xs) => GHC.Classes.Ord (Numeric.Tuple.Strict.Tuple xs) instance Numeric.Type.List.All GHC.Show.Show xs => GHC.Show.Show (Numeric.Tuple.Strict.Tuple xs) instance (Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All GHC.Read.Read xs) => GHC.Read.Read (Numeric.Tuple.Strict.Tuple xs) instance GHC.Read.Read a => GHC.Read.Read (Numeric.Tuple.Strict.Id a) instance GHC.Show.Show a => GHC.Show.Show (Numeric.Tuple.Strict.Id a) instance Data.Foldable.Foldable Numeric.Tuple.Strict.Id instance GHC.Base.Functor Numeric.Tuple.Strict.Id instance GHC.Base.Applicative Numeric.Tuple.Strict.Id instance GHC.Base.Monad Numeric.Tuple.Strict.Id instance Control.Monad.Fix.MonadFix Numeric.Tuple.Strict.Id instance Control.Monad.Zip.MonadZip Numeric.Tuple.Strict.Id module Numeric.Tuple.Lazy -- | This is an almost complete copy of Identity by (c) Andy Gill -- 2001. newtype Id a Id :: a -> Id a [runId] :: Id a -> a -- | A tuple indexed by a list of types type Tuple (xs :: [Type]) = TypedList Id xs -- | Type-indexed list data TypedList (f :: (k -> Type)) (xs :: [k]) -- | Grow a tuple on the left O(1). (*$) :: x -> Tuple xs -> Tuple (x :+ xs) infixr 5 *$ -- | Grow a tuple on the right. Note, it traverses an element list inside -- O(n). ($*) :: Tuple xs -> x -> Tuple (xs +: x) infixl 5 $* -- | Grow a tuple on the left while evaluating arguments to WHNF O(1). (*!) :: x -> Tuple xs -> Tuple (x :+ xs) infixr 5 *! -- | Grow a tuple on the right while evaluating arguments to WHNF. Note, it -- traverses an element list inside O(n). (!*) :: Tuple xs -> x -> Tuple (xs +: x) infixl 5 !* instance Data.Traversable.Traversable Numeric.Tuple.Lazy.Id instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Numeric.Tuple.Lazy.Id a) instance Data.Semigroup.Semigroup a => Data.Semigroup.Semigroup (Numeric.Tuple.Lazy.Id a) instance GHC.Float.RealFloat a => GHC.Float.RealFloat (Numeric.Tuple.Lazy.Id a) instance GHC.Real.RealFrac a => GHC.Real.RealFrac (Numeric.Tuple.Lazy.Id a) instance GHC.Real.Real a => GHC.Real.Real (Numeric.Tuple.Lazy.Id a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Numeric.Tuple.Lazy.Id a) instance GHC.Num.Num a => GHC.Num.Num (Numeric.Tuple.Lazy.Id a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Numeric.Tuple.Lazy.Id a) instance GHC.Arr.Ix a => GHC.Arr.Ix (Numeric.Tuple.Lazy.Id a) instance Data.String.IsString a => Data.String.IsString (Numeric.Tuple.Lazy.Id a) instance GHC.Real.Integral a => GHC.Real.Integral (Numeric.Tuple.Lazy.Id a) instance GHC.Generics.Generic1 Numeric.Tuple.Lazy.Id instance GHC.Generics.Generic (Numeric.Tuple.Lazy.Id a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.Tuple.Lazy.Id a) instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.Tuple.Lazy.Id a) instance Data.Bits.FiniteBits a => Data.Bits.FiniteBits (Numeric.Tuple.Lazy.Id a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.Tuple.Lazy.Id a) instance GHC.Enum.Enum a => GHC.Enum.Enum (Numeric.Tuple.Lazy.Id a) instance Data.Data.Data a => Data.Data.Data (Numeric.Tuple.Lazy.Id a) instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Numeric.Tuple.Lazy.Id a) instance Data.Bits.Bits a => Data.Bits.Bits (Numeric.Tuple.Lazy.Id a) instance Numeric.Type.List.All Data.Semigroup.Semigroup xs => Data.Semigroup.Semigroup (Numeric.Tuple.Lazy.Tuple xs) instance (Data.Semigroup.Semigroup (Numeric.Tuple.Lazy.Tuple xs), Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All GHC.Base.Monoid xs) => GHC.Base.Monoid (Numeric.Tuple.Lazy.Tuple xs) instance (Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All GHC.Enum.Bounded xs) => GHC.Enum.Bounded (Numeric.Tuple.Lazy.Tuple xs) instance Numeric.Type.List.All GHC.Classes.Eq xs => GHC.Classes.Eq (Numeric.Tuple.Lazy.Tuple xs) instance (Numeric.Type.List.All GHC.Classes.Eq xs, Numeric.Type.List.All GHC.Classes.Ord xs) => GHC.Classes.Ord (Numeric.Tuple.Lazy.Tuple xs) instance Numeric.Type.List.All GHC.Show.Show xs => GHC.Show.Show (Numeric.Tuple.Lazy.Tuple xs) instance (Numeric.TypedList.RepresentableList xs, Numeric.Type.List.All GHC.Read.Read xs) => GHC.Read.Read (Numeric.Tuple.Lazy.Tuple xs) instance GHC.Read.Read a => GHC.Read.Read (Numeric.Tuple.Lazy.Id a) instance GHC.Show.Show a => GHC.Show.Show (Numeric.Tuple.Lazy.Id a) instance Data.Foldable.Foldable Numeric.Tuple.Lazy.Id instance GHC.Base.Functor Numeric.Tuple.Lazy.Id instance GHC.Base.Applicative Numeric.Tuple.Lazy.Id instance GHC.Base.Monad Numeric.Tuple.Lazy.Id instance Control.Monad.Fix.MonadFix Numeric.Tuple.Lazy.Id instance Control.Monad.Zip.MonadZip Numeric.Tuple.Lazy.Id module Numeric.Tuple toStrict :: Tuple xs -> Tuple xs fromStrict :: Tuple xs -> Tuple xs -- | Provides a data type `Dims ds` to keep dimension sizes for -- multiple-dimensional data. Lower indices go first, i.e. assumed -- enumeration is i = i1 + i2*n1 + i3*n1*n2 + ... + ik*n1*n2*...*n(k-1). module Numeric.Dimensions.Dims -- | Type-level dimensionality O(1). type Dims (xs :: [k]) = TypedList Dim xs -- | Same as SomeNat, but for Dimensions: Hide all information about -- Dimensions inside data SomeDims SomeDims :: (Dims ns) -> SomeDims class Dimensions (ds :: [k]) -- | Get dimensionality of a space at runtime, represented as a list of -- Dim. -- -- Note, this function is supposed to be used with -- TypeApplications, and the Dimensions class has -- varying kind of the parameter; thus, the function has two type -- paremeters (kind and type of ds). For example, you can type: -- --
-- >>> :set -XTypeApplications -- -- >>> :set -XDataKinds -- -- >>> :t dims @_ @'[N 17, N 12] -- dims @_ @'[N 17, N 12] :: Dims '[N 17, N 12] ---- --
-- >>> :t dims @XNat @'[] -- dims @XNat @'[] :: Dims '[] ---- --
-- >>> :t dims @_ @(Tail '[3,2,5,7]) -- dims @_ @(Tail '[3,2,5,7]) :: Dims '[2, 5, 7] --dims :: Dimensions ds => Dims ds -- | Type-indexed list data TypedList (f :: (k -> Type)) (xs :: [k]) -- | Convert `Dims xs` to a plain haskell list of dimension sizes -- O(1). listDims :: Dims xs -> [Word] -- | Convert a plain haskell list of dimension sizes into an unknown -- type-level dimensionality O(1). someDimsVal :: [Word] -> SomeDims -- | Product of all dimension sizes O(Length xs). totalDim :: Dims xs -> Word -- | Product of all dimension sizes O(Length xs). totalDim' :: forall xs. Dimensions xs => Word -- | We either get evidence that this function was instantiated with the -- same type-level Dimensions, or Nothing O(Length xs). -- -- Note, this function works on Nat-indexed dimensions only, -- because Dims '[XN x] does not have runtime evidence to infer -- x and `KnownDim x` does not imply `KnownDim (XN x)`. sameDims :: Dims (as :: [Nat]) -> Dims (bs :: [Nat]) -> Maybe (Evidence (as ~ bs)) -- | We either get evidence that this function was instantiated with the -- same type-level Dimensions, or Nothing O(Length xs). sameDims' :: forall (as :: [Nat]) (bs :: [Nat]) p q. (Dimensions as, Dimensions bs) => p as -> q bs -> Maybe (Evidence (as ~ bs)) -- | Compare dimensions by their size in lexicorgaphic order from the last -- dimension to the first dimension (the last dimension is the most -- significant one). -- -- Literally, -- --
-- compareDims a b = compare (reverse $ listDims a) (reverse $ listDims b) --compareDims :: Dims as -> Dims bs -> Ordering -- | Compare dimensions by their size in lexicorgaphic order from the last -- dimension to the first dimension (the last dimension is the most -- significant one) O(Length xs). -- -- Literally, -- --
-- compareDims a b = compare (reverse $ listDims a) (reverse $ listDims b) ---- -- This is the same compare rule, as for Idxs. compareDims' :: forall as bs p q. (Dimensions as, Dimensions bs) => p as -> q bs -> Ordering -- | Similar to const or asProxyTypeOf; to be used on such -- implicit functions as dim, dimMax, etc. inSpaceOf :: a ds -> b ds -> a ds -- | Similar to asProxyTypeOf, Give a hint to type checker to fix -- the type of a function argument. asSpaceOf :: a ds -> (b ds -> c) -> (b ds -> c) -- | Get XNat-indexed dims given their fixed counterpart. xDims :: FixedDims xns ns => Dims ns -> Dims xns -- | Get XNat-indexed dims given their fixed counterpart. xDims' :: forall xns ns. (FixedDims xns ns, Dimensions ns) => Dims xns -- | Map Dims onto XDims (injective) -- | Map XDims onto Dims (injective) -- | Constrain Nat dimensions hidden behind XNats. -- | Know the structure of each dimension type KnownXNatTypes xns = All KnownXNatType xns -- | Synonym for (:+) that treats Nat values 0 and 1 in a special way: it -- preserves the property that all dimensions are greater than 1. -- | Synonym for (+:) that treats Nat values 0 and 1 in a special way: it -- preserves the property that all dimensions are greater than 1. -- | Representable type lists. Allows getting type information about list -- structure at runtime. class RepresentableList (xs :: [k]) -- | Get type-level constructed list tList :: RepresentableList xs => TypeList xs -- | A list of type proxies type TypeList (xs :: [k]) = TypedList Proxy xs -- | Get a constructible TypeList from any other TypedList; -- Pattern matching agains the result brings RepresentableList -- constraint into the scope: -- --
-- case types ts of TypeList -> ... --types :: TypedList f xs -> TypeList xs order :: TypedList f xs -> Dim (Length xs) order' :: forall xs. RepresentableList xs => Dim (Length xs) instance Numeric.Dimensions.Dims.Dimensions '[] instance forall k (d :: k) (ds :: [k]). (Numeric.Dim.KnownDim d, Numeric.Dimensions.Dims.Dimensions ds) => Numeric.Dimensions.Dims.Dimensions (d : ds) instance forall k (ds :: [k]). Numeric.Dimensions.Dims.Dimensions ds => GHC.Enum.Bounded (Numeric.Dimensions.Dims.Dims ds) instance GHC.Classes.Eq Numeric.Dimensions.Dims.SomeDims instance GHC.Classes.Ord Numeric.Dimensions.Dims.SomeDims instance GHC.Show.Show Numeric.Dimensions.Dims.SomeDims instance GHC.Read.Read Numeric.Dimensions.Dims.SomeDims instance GHC.Classes.Eq (Numeric.Dimensions.Dims.Dims ds) instance GHC.Classes.Eq (Numeric.Dimensions.Dims.Dims ds) instance GHC.Classes.Ord (Numeric.Dimensions.Dims.Dims ds) instance GHC.Classes.Ord (Numeric.Dimensions.Dims.Dims ds) instance forall k (xs :: [k]). GHC.Show.Show (Numeric.Dimensions.Dims.Dims xs) -- | Provides a data type Idx that enumerates through multiple dimensions. -- Lower indices go first, i.e. assumed enumeration is i = i1 + i2*n1 + -- i3*n1*n2 + ... + ik*n1*n2*...*n(k-1). This is also to encourage -- column-first matrix enumeration and array layout. module Numeric.Dimensions.Idxs -- | This type is used to index a single dimension; the range of indices is -- from 1 to n. -- -- Note, this type has a weird Enum instance: -- --
-- >>> fromEnum (Idx 7) -- 6 ---- -- The logic behind this is that the Enum class is used to -- transform indices to offsets. That is, element of an array at index -- k :: Idx n is the element taken by an offset `k - 1 :: Int`. newtype Idx n Idx :: Word -> Idx n [unIdx] :: Idx n -> Word -- | Type-level dimensional indexing with arbitrary Word values inside. -- Most of the operations on it require Dimensions constraint, -- because the Idxs itself does not store info about dimension -- bounds. -- -- Note, this type has a special Enum instance: fromEnum -- gives an offset of the index in a flat 1D array; this is in line with -- a weird Enum instance of Idx type. type Idxs (xs :: [k]) = TypedList Idx xs idxFromWord :: forall d. KnownDim d => Word -> Maybe (Idx d) unsafeIdxFromWord :: forall d. KnownDim d => Word -> Idx d idxToWord :: Idx d -> Word listIdxs :: Idxs xs -> [Word] idxsFromWords :: forall ds. Dimensions ds => [Word] -> Maybe (Idx ds) instance forall k (n :: k). GHC.Classes.Ord (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). GHC.Classes.Eq (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). Foreign.Storable.Storable (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). Numeric.Dim.KnownDim n => GHC.Real.Real (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). Numeric.Dim.KnownDim n => GHC.Real.Integral (Numeric.Dimensions.Idxs.Idx n) instance GHC.Generics.Generic1 Numeric.Dimensions.Idxs.Idx instance forall k (n :: k). GHC.Generics.Generic (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). (Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable n) => Data.Data.Data (Numeric.Dimensions.Idxs.Idx n) instance forall k (xs :: [k]). GHC.Classes.Eq (Numeric.Dimensions.Idxs.Idxs xs) instance forall k (xs :: [k]). GHC.Classes.Ord (Numeric.Dimensions.Idxs.Idxs xs) instance forall k (xs :: [k]). GHC.Show.Show (Numeric.Dimensions.Idxs.Idxs xs) instance forall k (n :: k). Numeric.Dim.KnownDim n => GHC.Num.Num (Numeric.Dimensions.Idxs.Idxs '[n]) instance forall k (ds :: [k]). Numeric.Dimensions.Dims.Dimensions ds => GHC.Enum.Bounded (Numeric.Dimensions.Idxs.Idxs ds) instance forall k (ds :: [k]). Numeric.Dimensions.Dims.Dimensions ds => GHC.Enum.Enum (Numeric.Dimensions.Idxs.Idxs ds) instance forall k (n :: k). GHC.Read.Read (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). GHC.Show.Show (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). Numeric.Dim.KnownDim n => GHC.Enum.Bounded (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). Numeric.Dim.KnownDim n => GHC.Enum.Enum (Numeric.Dimensions.Idxs.Idx n) instance forall k (n :: k). Numeric.Dim.KnownDim n => GHC.Num.Num (Numeric.Dimensions.Idxs.Idx n) -- | Fold a function over all dimensions provided dimension indices or -- offsets. The main purpose of this module is to fold or traverse flat -- data arrays following the shape of dimensions associated with them. module Numeric.Dimensions.Fold -- | Go over all dimensions keeping track of index and offset overDim :: Monad m => Dims ds -> (Idxs ds -> Int -> a -> m a) -> Int -> Int -> a -> m a -- | Go over all dimensions keeping track of index and offset overDim_ :: Monad m => Dims ds -> (Idxs ds -> Int -> m ()) -> Int -> Int -> m () -- | Go over all dimensions keeping track of index overDimIdx :: Monad m => Dims ds -> (Idxs ds -> a -> m a) -> a -> m a -- | Go over all dimensions keeping track of index overDimIdx_ :: Monad m => Dims ds -> (Idxs ds -> m ()) -> m () -- | Go over all dimensions keeping track of total offset overDimOff :: Monad m => Dims ds -> (Int -> a -> m a) -> Int -> Int -> a -> m a -- | Go over all dimensions keeping track of total offset overDimOff_ :: Monad m => Dims ds -> (Int -> m ()) -> Int -> Int -> m () -- | Go over all dimensions in reverse order keeping track of index and -- offset overDimReverse :: Monad m => Dims ds -> (Idxs ds -> Int -> a -> m a) -> Int -> Int -> a -> m a -- | Go over all dimensions in reverse order keeping track of index overDimReverseIdx :: Monad m => Dims ds -> (Idxs ds -> a -> m a) -> a -> m a -- | Fold over all dimensions keeping track of index and offset foldDim :: Dims ds -> (Idxs ds -> Int -> a -> a) -> Int -> Int -> a -> a -- | Fold over all dimensions keeping track of index foldDimIdx :: Dims ds -> (Idxs ds -> a -> a) -> a -> a -- | Fold over all dimensions keeping track of total offset foldDimOff :: Dims ds -> (Int -> a -> a) -> Int -> Int -> a -> a -- | Fold over all dimensions in reverse order keeping track of index and -- offset foldDimReverse :: Dims ds -> (Idxs ds -> Int -> a -> a) -> Int -> Int -> a -> a -- | Fold over all dimensions in reverse order keeping track of index foldDimReverseIdx :: Dims ds -> (Idxs ds -> a -> a) -> a -> a -- | Traverse from the first index to the second index in each dimension. -- You can combine positive and negative traversal directions along -- different dimensions. -- -- Note, initial and final indices are included in the range; the -- argument function is guaranteed to execute at least once. overDimPart :: (Dimensions ds, Monad m) => Idxs ds -> Idxs ds -> (Idxs ds -> Int -> a -> m a) -> Int -> Int -> a -> m a -- | Traverse from the first index to the second index in each dimension. -- You can combine positive and negative traversal directions along -- different dimensions. -- -- Note, initial and final indices are included in the range; the -- argument function is guaranteed to execute at least once. overDimPartIdx :: Monad m => Idxs ds -> Idxs ds -> (Idxs ds -> a -> m a) -> a -> m a -- | Provides a set of data types to define and traverse through multiple -- dimensions. The core types are `Dims ds` and `Idxs ds`, which fix -- dimension sizes at compile time. -- -- Lower indices go first, i.e. assumed enumeration is i = i1 + i2*n1 + -- i3*n1*n2 + ... + ik*n1*n2*...*n(k-1). This is also to encourage -- column-first matrix enumeration and array layout. module Numeric.Dimensions