-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Generic heterogeneous vectors
--   
--   Generic heterogeneous vectors
@package fixed-vector-hetero
@version 0.4.0.0


-- | Type functions
module Data.Vector.HFixed.TypeFuns

-- | A concrete, poly-kinded proxy type
data Proxy k (t :: k) :: forall k. () => k -> *
Proxy :: Proxy k
proxy :: t -> Proxy t

-- | Concaternation of type level lists.

-- | Length of type list expressed as type level naturals from
--   <tt>fixed-vector</tt>.

-- | Homogeneous type list with length <i>n</i> and element of type
--   <i>a</i>. It uses type level natural defined in <tt>fixed-vector</tt>.

module Data.Vector.HFixed.Class

-- | Type family for N-ary function. Types of function parameters are
--   encoded as the list of types.

-- | Newtype wrapper to work around of type families' lack of injectivity.
type Fun = TFun Identity

-- | Newtype wrapper for function where all type parameters have same type
--   constructor. This type is required for writing function which works
--   with monads, appicatives etc.
newtype TFun f as b
TFun :: Fn f as b -> TFun f as b
[unTFun] :: TFun f as b -> Fn f as b

-- | A concrete, poly-kinded proxy type
data Proxy k (t :: k) :: forall k. () => k -> *
Proxy :: Proxy k

-- | Concaternation of type level lists.

-- | Length of type list expressed as type level naturals from
--   <tt>fixed-vector</tt>.

-- | Homogeneous type list with length <i>n</i> and element of type
--   <i>a</i>. It uses type level natural defined in <tt>fixed-vector</tt>.

-- | Type class for dealing with N-ary function in generic way. Both
--   <a>accum</a> and <a>apply</a> work with accumulator data types which
--   are polymorphic. So it's only possible to write functions which
--   rearrange elements in vector using plain ADT. It's possible to get
--   around it by using GADT as accumulator (See <a>ArityC</a> and function
--   which use it)
--   
--   This is also somewhat a kitchen sink module. It contains witnesses
--   which could be used to prove type equalities or to bring instance in
--   scope.
class Arity (xs :: [*])

-- | Fold over <i>N</i> elements exposed as N-ary function.
accum :: Arity xs => (forall a as. t (a : as) -> f a -> t as) -> (t '[] -> b) -> t xs -> TFun f xs b

-- | Apply values to N-ary function
apply :: Arity xs => (forall a as. t (a : as) -> (f a, t as)) -> t xs -> ContVecF xs f

-- | Size of type list as integer.
arity :: Arity xs => p xs -> Int
class (Arity xs) => ArityC c xs
accumC :: ArityC c xs => proxy c -> (forall a as. (c a) => t (a : as) -> f a -> t as) -> (t '[] -> b) -> t xs -> TFun f xs b

-- | Apply values to N-ary function
applyC :: ArityC c xs => proxy c -> (forall a as. (c a) => t (a : as) -> (f a, t as)) -> t xs -> ContVecF xs f

-- | Type class for heterogeneous vectors. Instance should specify way to
--   construct and deconstruct itself
--   
--   Note that this type class is extremely generic. Almost any single
--   constructor data type could be made instance. It could be monomorphic,
--   it could be polymorphic in some or all fields it doesn't matter. Only
--   law instance should obey is:
--   
--   <pre>
--   inspect v construct = v
--   </pre>
--   
--   Default implementation which uses <a>Generic</a> is provided.
class Arity (Elems v) => HVector v where {
    type family Elems v :: [*];
    type Elems v = GElems (Rep v);
}

-- | Function for constructing vector
construct :: HVector v => Fun (Elems v) v

-- | Function for constructing vector
construct :: (HVector v, Generic v, GHVector (Rep v), GElems (Rep v) ~ Elems v) => Fun (Elems v) v

-- | Function for deconstruction of vector. It applies vector's elements to
--   N-ary function.
inspect :: HVector v => v -> Fun (Elems v) a -> a

-- | Function for deconstruction of vector. It applies vector's elements to
--   N-ary function.
inspect :: (HVector v, Generic v, GHVector (Rep v), GElems (Rep v) ~ Elems v) => v -> Fun (Elems v) a -> a

-- | Number of elements in tuple
tupleSize :: forall v proxy. HVector v => proxy v -> Int

-- | Type class for partially homogeneous vector where every element in the
--   vector have same type constructor. Vector itself is parametrized by
--   that constructor
class Arity (ElemsF v) => HVectorF (v :: (* -> *) -> *) where {
    type family ElemsF v :: [*];
}
inspectF :: HVectorF v => v f -> TFun f (ElemsF v) a -> a
constructF :: HVectorF v => TFun f (ElemsF v) (v f)

-- | Number of elements in tuple
tupleSizeF :: forall v f proxy. HVectorF v => proxy (v f) -> Int

-- | CPS-encoded heterogeneous vector.
type ContVec xs = ContVecF xs Identity

-- | CPS-encoded partially heterogeneous vector.
newtype ContVecF xs f
ContVecF :: (forall r. TFun f xs r -> r) -> ContVecF xs f
[runContVecF] :: ContVecF xs f -> forall r. TFun f xs r -> r

-- | Cons element to the vector
cons :: x -> ContVec xs -> ContVec (x : xs)

-- | Cons element to the vector
consF :: f x -> ContVecF xs f -> ContVecF (x : xs) f

-- | Conversion between homogeneous and heterogeneous N-ary functions.
class (ArityPeano n, Arity (HomList n a)) => HomArity n a

-- | Convert n-ary homogeneous function to heterogeneous.
toHeterogeneous :: HomArity n a => Fun n a r -> Fun (HomList n a) r

-- | Convert heterogeneous n-ary function to homogeneous.
toHomogeneous :: HomArity n a => Fun (HomList n a) r -> Fun n a r

-- | Default implementation of <a>inspect</a> for homogeneous vector.
homInspect :: (Vector v a, HomArity (Peano (Dim v)) a) => v a -> Fun (HomList (Peano (Dim v)) a) r -> r

-- | Default implementation of <a>construct</a> for homogeneous vector.
homConstruct :: forall v a. (Vector v a, HomArity (Peano (Dim v)) a) => Fun (HomList (Peano (Dim v)) a) (v a)

-- | Apply single parameter to function
curryFun :: Fun (x : xs) r -> x -> Fun xs r

-- | Uncurry N-ary function.
uncurryFun :: (x -> Fun xs r) -> Fun (x : xs) r

-- | Conversion function
uncurryMany :: forall xs ys r. Arity xs => Fun xs (Fun ys r) -> Fun (xs ++ ys) r

-- | Curry first <i>n</i> arguments of N-ary function.
curryMany :: forall xs ys r. Arity xs => Fun (xs ++ ys) r -> Fun xs (Fun ys r)

-- | Add one parameter to function which is ignored.
constFun :: Fun xs r -> Fun (x : xs) r

-- | Add one parameter to function which is ignored.
constTFun :: TFun f xs r -> TFun f (x : xs) r

-- | Apply single parameter to function
curryTFun :: TFun f (x : xs) r -> f x -> TFun f xs r

-- | Uncurry single parameter
uncurryTFun :: (f x -> TFun f xs r) -> TFun f (x : xs) r

-- | Move first argument of function to its result. This function is useful
--   for implementation of lens.
shuffleTF :: forall f x xs r. Arity xs => (x -> TFun f xs r) -> TFun f xs (x -> r)

-- | Transform function but leave outermost parameter untouched.
stepTFun :: (TFun f xs a -> TFun f ys b) -> (TFun f (x : xs) a -> TFun f (x : ys) b)

-- | Concatenate n-ary functions. This function combine results of both
--   N-ary functions and merge their parameters into single list.
concatF :: (Arity xs, Arity ys) => (a -> b -> c) -> Fun xs a -> Fun ys b -> Fun (xs ++ ys) c

-- | Helper for lens implementation.
lensWorkerF :: forall f r x y xs. (Functor f, Arity xs) => (x -> f y) -> Fun (y : xs) r -> Fun (x : xs) (f r)

-- | Helper for lens implementation.
lensWorkerTF :: forall f g r x y xs. (Functor f, Arity xs) => (g x -> f (g y)) -> TFun g (y : xs) r -> TFun g (x : xs) (f r)

-- | Indexing of vectors
class ArityPeano n => Index (n :: PeanoNum) (xs :: [*]) where {
    type family ValueAt n xs :: *;
    type family NewElems n xs a :: [*];
}

-- | Getter function for vectors
getF :: Index n xs => proxy n -> Fun xs (ValueAt n xs)

-- | Putter function. It applies value <tt>x</tt> to <tt>n</tt>th parameter
--   of function.
putF :: Index n xs => proxy n -> ValueAt n xs -> Fun xs r -> Fun xs r

-- | Helper for implementation of lens
lensF :: (Index n xs, Functor f, v ~ ValueAt n xs) => proxy n -> (v -> f v) -> Fun xs r -> Fun xs (f r)

-- | Helper for type-changing lens
lensChF :: (Index n xs, (Functor f)) => proxy n -> (ValueAt n xs -> f a) -> Fun (NewElems n xs a) r -> Fun xs (f r)
instance (Data.Vector.HFixed.Class.HomArity (Data.Vector.Fixed.Cont.Peano n) a, GHC.TypeNats.KnownNat n, Data.Vector.Fixed.Cont.Peano (n GHC.TypeNats.+ 1) ~ 'Data.Vector.Fixed.Cont.S (Data.Vector.Fixed.Cont.Peano n)) => Data.Vector.HFixed.Class.HVector (Data.Vector.Fixed.Boxed.Vec n a)
instance (Data.Vector.Fixed.Unboxed.Unbox n a, Data.Vector.HFixed.Class.HomArity (Data.Vector.Fixed.Cont.Peano n) a, GHC.TypeNats.KnownNat n, Data.Vector.Fixed.Cont.Peano (n GHC.TypeNats.+ 1) ~ 'Data.Vector.Fixed.Cont.S (Data.Vector.Fixed.Cont.Peano n)) => Data.Vector.HFixed.Class.HVector (Data.Vector.Fixed.Unboxed.Vec n a)
instance (Foreign.Storable.Storable a, Data.Vector.HFixed.Class.HomArity (Data.Vector.Fixed.Cont.Peano n) a, GHC.TypeNats.KnownNat n, Data.Vector.Fixed.Cont.Peano (n GHC.TypeNats.+ 1) ~ 'Data.Vector.Fixed.Cont.S (Data.Vector.Fixed.Cont.Peano n)) => Data.Vector.HFixed.Class.HVector (Data.Vector.Fixed.Storable.Vec n a)
instance (Data.Primitive.Types.Prim a, Data.Vector.HFixed.Class.HomArity (Data.Vector.Fixed.Cont.Peano n) a, GHC.TypeNats.KnownNat n, Data.Vector.Fixed.Cont.Peano (n GHC.TypeNats.+ 1) ~ 'Data.Vector.Fixed.Cont.S (Data.Vector.Fixed.Cont.Peano n)) => Data.Vector.HFixed.Class.HVector (Data.Vector.Fixed.Primitive.Vec n a)
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.HVector (Data.Vector.HFixed.Class.ContVecF xs Data.Functor.Identity.Identity)
instance Data.Vector.HFixed.Class.HVector ()
instance Data.Vector.HFixed.Class.HVector (Data.Complex.Complex a)
instance Data.Vector.HFixed.Class.HVector (a, b)
instance Data.Vector.HFixed.Class.HVector (a, b, c)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a')
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a', b')
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a', b', c')
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a', b', c', d')
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a', b', c', d', e')
instance Data.Vector.HFixed.Class.HVector (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a', b', c', d', e', f')
instance (Data.Vector.HFixed.Class.GHVector f, Data.Vector.HFixed.Class.Arity (Data.Vector.HFixed.Class.GElems f)) => Data.Vector.HFixed.Class.GHVector (GHC.Generics.M1 i c f)
instance (Data.Vector.HFixed.Class.GHVector f, Data.Vector.HFixed.Class.GHVector g, Data.Vector.HFixed.Class.Arity (Data.Vector.HFixed.Class.GElems f), Data.Vector.HFixed.Class.Arity (Data.Vector.HFixed.Class.GElems g)) => Data.Vector.HFixed.Class.GHVector (f GHC.Generics.:*: g)
instance Data.Vector.HFixed.Class.GHVector (GHC.Generics.K1 GHC.Generics.R x)
instance Data.Vector.HFixed.Class.GHVector GHC.Generics.U1
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.Index 'Data.Vector.Fixed.Cont.Z (x : xs)
instance Data.Vector.HFixed.Class.Index n xs => Data.Vector.HFixed.Class.Index ('Data.Vector.Fixed.Cont.S n) (x : xs)
instance Data.Vector.HFixed.Class.Arity xs => GHC.Base.Applicative (Data.Vector.HFixed.Class.TFun f xs)
instance Data.Vector.HFixed.Class.Arity xs => GHC.Base.Functor (Data.Vector.HFixed.Class.TFun f xs)
instance Data.Vector.HFixed.Class.ArityC c '[]
instance (c x, Data.Vector.HFixed.Class.ArityC c xs) => Data.Vector.HFixed.Class.ArityC c (x : xs)
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.HVectorF (Data.Vector.HFixed.Class.ContVecF xs)
instance Data.Vector.HFixed.Class.HomArity 'Data.Vector.Fixed.Cont.Z a
instance Data.Vector.HFixed.Class.HomArity n a => Data.Vector.HFixed.Class.HomArity ('Data.Vector.Fixed.Cont.S n) a
instance Data.Vector.HFixed.Class.Arity '[]
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.Arity (x : xs)
instance Data.Vector.HFixed.Class.Arity xs => GHC.Base.Monad (Data.Vector.HFixed.Class.TFun f xs)


-- | CPS encoded heterogeneous vectors.
module Data.Vector.HFixed.Cont

-- | Type family for N-ary function. Types of function parameters are
--   encoded as the list of types.

-- | Newtype wrapper to work around of type families' lack of injectivity.
type Fun = TFun Identity

-- | Newtype wrapper for function where all type parameters have same type
--   constructor. This type is required for writing function which works
--   with monads, appicatives etc.
newtype TFun f as b
TFun :: Fn f as b -> TFun f as b
[unTFun] :: TFun f as b -> Fn f as b

-- | Type class for dealing with N-ary function in generic way. Both
--   <a>accum</a> and <a>apply</a> work with accumulator data types which
--   are polymorphic. So it's only possible to write functions which
--   rearrange elements in vector using plain ADT. It's possible to get
--   around it by using GADT as accumulator (See <a>ArityC</a> and function
--   which use it)
--   
--   This is also somewhat a kitchen sink module. It contains witnesses
--   which could be used to prove type equalities or to bring instance in
--   scope.
class Arity (xs :: [*])

-- | Fold over <i>N</i> elements exposed as N-ary function.
accum :: Arity xs => (forall a as. t (a : as) -> f a -> t as) -> (t '[] -> b) -> t xs -> TFun f xs b

-- | Apply values to N-ary function
apply :: Arity xs => (forall a as. t (a : as) -> (f a, t as)) -> t xs -> ContVecF xs f

-- | Size of type list as integer.
arity :: Arity xs => p xs -> Int

-- | Type class for heterogeneous vectors. Instance should specify way to
--   construct and deconstruct itself
--   
--   Note that this type class is extremely generic. Almost any single
--   constructor data type could be made instance. It could be monomorphic,
--   it could be polymorphic in some or all fields it doesn't matter. Only
--   law instance should obey is:
--   
--   <pre>
--   inspect v construct = v
--   </pre>
--   
--   Default implementation which uses <a>Generic</a> is provided.
class Arity (Elems v) => HVector v where {
    type family Elems v :: [*];
    type Elems v = GElems (Rep v);
}

-- | Function for constructing vector
construct :: HVector v => Fun (Elems v) v

-- | Function for constructing vector
construct :: (HVector v, Generic v, GHVector (Rep v), GElems (Rep v) ~ Elems v) => Fun (Elems v) v

-- | Function for deconstruction of vector. It applies vector's elements to
--   N-ary function.
inspect :: HVector v => v -> Fun (Elems v) a -> a

-- | Function for deconstruction of vector. It applies vector's elements to
--   N-ary function.
inspect :: (HVector v, Generic v, GHVector (Rep v), GElems (Rep v) ~ Elems v) => v -> Fun (Elems v) a -> a

-- | Number of elements in tuple
tupleSize :: forall v proxy. HVector v => proxy v -> Int

-- | Type class for partially homogeneous vector where every element in the
--   vector have same type constructor. Vector itself is parametrized by
--   that constructor
class Arity (ElemsF v) => HVectorF (v :: (* -> *) -> *) where {
    type family ElemsF v :: [*];
}
inspectF :: HVectorF v => v f -> TFun f (ElemsF v) a -> a
constructF :: HVectorF v => TFun f (ElemsF v) (v f)

-- | Number of elements in tuple
tupleSizeF :: forall v f proxy. HVectorF v => proxy (v f) -> Int

-- | Indexing of vectors
class ArityPeano n => Index (n :: PeanoNum) (xs :: [*]) where {
    type family ValueAt n xs :: *;
}

-- | CPS-encoded heterogeneous vector.
type ContVec xs = ContVecF xs Identity

-- | CPS-encoded partially heterogeneous vector.
newtype ContVecF xs f
ContVecF :: (forall r. TFun f xs r -> r) -> ContVecF xs f
[runContVecF] :: ContVecF xs f -> forall r. TFun f xs r -> r

-- | List like heterogeneous vector.
data VecList :: [*] -> *
[Nil] :: VecList '[]
[Cons] :: x -> VecList xs -> VecList (x : xs)

-- | List-like vector
data VecListF xs f
[NilF] :: VecListF '[] f
[ConsF] :: f x -> VecListF xs f -> VecListF (x : xs) f

-- | Convert heterogeneous vector to CPS form
cvec :: (HVector v, Elems v ~ xs) => v -> ContVec xs

-- | Convert CPS-vector to heterogeneous vector
vector :: (HVector v, Elems v ~ xs) => ContVec xs -> v
cvecF :: HVectorF v => v f -> ContVecF (ElemsF v) f
vectorF :: HVectorF v => ContVecF (ElemsF v) f -> v f

-- | Head of vector
head :: Arity xs => ContVec (x : xs) -> x

-- | Tail of CPS-encoded vector
tail :: ContVec (x : xs) -> ContVec xs

-- | Cons element to the vector
cons :: x -> ContVec xs -> ContVec (x : xs)

-- | Cons element to the vector
consF :: f x -> ContVecF xs f -> ContVecF (x : xs) f

-- | Concatenate two vectors
concat :: Arity xs => ContVec xs -> ContVec ys -> ContVec (xs ++ ys)

-- | Get value at <tt>n</tt>th position.
index :: Index n xs => ContVec xs -> proxy n -> ValueAt n xs

-- | Set value on nth position.
set :: Index n xs => proxy n -> ValueAt n xs -> ContVec xs -> ContVec xs

-- | Left fold over vector
foldlF :: (ArityC c xs) => Proxy c -> (forall a. c a => b -> f a -> b) -> b -> ContVecF xs f -> b

-- | Right fold over vector
foldrF :: (ArityC c xs) => Proxy c -> (forall a. c a => f a -> b -> b) -> b -> ContVecF xs f -> b

-- | Left fold over vector
foldlNatF :: (Arity xs) => (forall a. b -> f a -> b) -> b -> ContVecF xs f -> b

-- | Right fold over vector
foldrNatF :: (Arity xs) => (forall a. f a -> b -> b) -> b -> ContVecF xs f -> b

-- | Unfold vector.
unfoldrF :: (ArityC c xs) => Proxy c -> (forall a. c a => b -> (f a, b)) -> b -> ContVecF xs f
replicateF :: forall f c xs. ArityC c xs => Proxy c -> (forall a. c a => f a) -> ContVecF xs f
replicateNatF :: forall f xs. Arity xs => (forall a. f a) -> ContVecF xs f

-- | Zip two heterogeneous vectors
zipWithF :: forall xs f g h c. (ArityC c xs) => Proxy c -> (forall a. c a => f a -> g a -> h a) -> ContVecF xs f -> ContVecF xs g -> ContVecF xs h

-- | Zip two heterogeneous vectors
zipWithNatF :: forall xs f g h. (Arity xs) => (forall a. f a -> g a -> h a) -> ContVecF xs f -> ContVecF xs g -> ContVecF xs h

-- | Zip vector and fold result using monoid
zipFoldF :: forall xs c m f. (ArityC c xs, Monoid m) => Proxy c -> (forall a. c a => f a -> f a -> m) -> ContVecF xs f -> ContVecF xs f -> m

-- | Convert heterogeneous vector to homogeneous
monomorphizeF :: forall c xs a f n. (ArityC c xs, Peano n ~ Len xs) => Proxy c -> (forall x. c x => f x -> a) -> ContVecF xs f -> ContVec n a

-- | Apply natural transformation to every element of the tuple.
mapNat :: (Arity xs) => (forall a. f a -> g a) -> ContVecF xs f -> ContVecF xs g

-- | Apply sequence to outer level of parametrized tuple elements.
sequenceF :: (Arity xs, Applicative f) => ContVecF xs (f `Compose` g) -> f (ContVecF xs g)
distributeF :: forall f g xs. (Arity xs, Functor f) => f (ContVecF xs g) -> ContVecF xs (f `Compose` g)
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.HVectorF (Data.Vector.HFixed.Cont.VecListF xs)
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.HVector (Data.Vector.HFixed.Cont.VecList xs)


-- | Heterogeneous vectors.
module Data.Vector.HFixed

-- | Type class for dealing with N-ary function in generic way. Both
--   <a>accum</a> and <a>apply</a> work with accumulator data types which
--   are polymorphic. So it's only possible to write functions which
--   rearrange elements in vector using plain ADT. It's possible to get
--   around it by using GADT as accumulator (See <a>ArityC</a> and function
--   which use it)
--   
--   This is also somewhat a kitchen sink module. It contains witnesses
--   which could be used to prove type equalities or to bring instance in
--   scope.
class Arity (xs :: [*])
class (Arity xs) => ArityC c xs

-- | Type class for heterogeneous vectors. Instance should specify way to
--   construct and deconstruct itself
--   
--   Note that this type class is extremely generic. Almost any single
--   constructor data type could be made instance. It could be monomorphic,
--   it could be polymorphic in some or all fields it doesn't matter. Only
--   law instance should obey is:
--   
--   <pre>
--   inspect v construct = v
--   </pre>
--   
--   Default implementation which uses <a>Generic</a> is provided.
class Arity (Elems v) => HVector v where {
    type family Elems v :: [*];
    type Elems v = GElems (Rep v);
}

-- | Function for constructing vector
construct :: HVector v => Fun (Elems v) v

-- | Function for constructing vector
construct :: (HVector v, Generic v, GHVector (Rep v), GElems (Rep v) ~ Elems v) => Fun (Elems v) v

-- | Function for deconstruction of vector. It applies vector's elements to
--   N-ary function.
inspect :: HVector v => v -> Fun (Elems v) a -> a

-- | Function for deconstruction of vector. It applies vector's elements to
--   N-ary function.
inspect :: (HVector v, Generic v, GHVector (Rep v), GElems (Rep v) ~ Elems v) => v -> Fun (Elems v) a -> a

-- | Number of elements in tuple
tupleSize :: forall v proxy. HVector v => proxy v -> Int

-- | Type class for partially homogeneous vector where every element in the
--   vector have same type constructor. Vector itself is parametrized by
--   that constructor
class Arity (ElemsF v) => HVectorF (v :: (* -> *) -> *) where {
    type family ElemsF v :: [*];
}
inspectF :: HVectorF v => v f -> TFun f (ElemsF v) a -> a
constructF :: HVectorF v => TFun f (ElemsF v) (v f)

-- | Number of elements in tuple
tupleSizeF :: forall v f proxy. HVectorF v => proxy (v f) -> Int

-- | A concrete, poly-kinded proxy type
data Proxy k (t :: k) :: forall k. () => k -> *
Proxy :: Proxy k

-- | CPS-encoded heterogeneous vector.
type ContVec xs = ContVecF xs Identity

-- | CPS-encoded partially heterogeneous vector.
newtype ContVecF xs f
ContVecF :: (forall r. TFun f xs r -> r) -> ContVecF xs f
[runContVecF] :: ContVecF xs f -> forall r. TFun f xs r -> r

-- | Restrict type of vector to <a>ContVec</a>. This function is useful for
--   resolving type ambiguity when composing functions. For example
--   following code would not compile because intermediate type is
--   ambiguous:
--   
--   <pre>
--   cons 'a' . tail
--   </pre>
--   
--   GHC cannot guess what type should be produced by <tt>tail</tt>.
--   However we can fix type of intermediate vector with <tt>asCVec</tt>,
--   so code below will work just fine:
--   
--   <pre>
--   cons 'a' . asCVec . tail
--   </pre>
asCVec :: ContVec xs -> ContVec xs
asCVecF :: ContVecF f xs -> ContVecF f xs

-- | We can convert between any two vector which have same structure but
--   different representations.
convert :: (HVector v, HVector w, Elems v ~ Elems w) => v -> w

-- | Head of the vector
head :: (HVector v, Elems v ~ (a : as), Arity as) => v -> a

-- | Tail of the vector
--   
--   <pre>
--   &gt;&gt;&gt; case tail ('a',"aa",()) of x@(_,_) -&gt; x
--   ("aa",())
--   </pre>
tail :: (HVector v, HVector w, (a : Elems w) ~ Elems v) => v -> w

-- | Prepend element to the list. Note that it changes type of vector so it
--   either must be known from context of specified explicitly
cons :: (HVector v, HVector w, Elems w ~ (a : Elems v)) => a -> v -> w

-- | Concatenate two vectors
concat :: (HVector v, HVector u, HVector w, Elems w ~ (Elems v ++ Elems u)) => v -> u -> w

-- | Indexing of vectors
class ArityPeano n => Index (n :: PeanoNum) (xs :: [*]) where {
    type family ValueAt n xs :: *;
}

-- | Index heterogeneous vector
index :: (Index n (Elems v), HVector v) => v -> proxy n -> ValueAt n (Elems v)

-- | Set element in the vector
set :: (Index n (Elems v), HVector v) => proxy n -> ValueAt n (Elems v) -> v -> v

-- | Twan van Laarhoven's lens for i'th element.
element :: forall n v a f proxy. (Index (Peano n) (Elems v), ValueAt (Peano n) (Elems v) ~ a, HVector v, Functor f) => proxy n -> (a -> f a) -> (v -> f v)

-- | Type changing Twan van Laarhoven's lens for i'th element.
elementCh :: forall n v w a b f proxy. (Index (Peano n) (Elems v), ValueAt (Peano n) (Elems v) ~ a, HVector v, HVector w, Elems w ~ NewElems (Peano n) (Elems v) b, Functor f) => proxy n -> (a -> f b) -> (v -> f w)
mk0 :: forall v. (HVector v, Elems v ~ '[]) => v
mk1 :: forall v a. (HVector v, Elems v ~ '[a]) => a -> v
mk2 :: forall v a b. (HVector v, Elems v ~ '[a, b]) => a -> b -> v
mk3 :: forall v a b c. (HVector v, Elems v ~ '[a, b, c]) => a -> b -> c -> v
mk4 :: forall v a b c d. (HVector v, Elems v ~ '[a, b, c, d]) => a -> b -> c -> d -> v
mk5 :: forall v a b c d e. (HVector v, Elems v ~ '[a, b, c, d, e]) => a -> b -> c -> d -> e -> v

-- | Most generic form of fold which doesn't constrain elements id use of
--   <a>inspect</a>. Or in more convenient form below:
--   
--   <pre>
--   &gt;&gt;&gt; fold (12::Int,"Str") (\a s -&gt; show a ++ s)
--   "12Str"
--   </pre>
fold :: HVector v => v -> Fn Identity (Elems v) r -> r

-- | Right fold over heterogeneous vector
foldr :: (HVector v, ArityC c (Elems v)) => Proxy c -> (forall a. c a => a -> b -> b) -> b -> v -> b

-- | Left fold over heterogeneous vector
foldl :: (HVector v, ArityC c (Elems v)) => Proxy c -> (forall a. c a => b -> a -> b) -> b -> v -> b

-- | Right fold over heterogeneous vector
foldrF :: (HVectorF v, ArityC c (ElemsF v)) => Proxy c -> (forall a. c a => f a -> b -> b) -> b -> v f -> b

-- | Left fold over heterogeneous vector
foldlF :: (HVectorF v, ArityC c (ElemsF v)) => Proxy c -> (forall a. c a => b -> f a -> b) -> b -> v f -> b

-- | Right fold over heterogeneous vector
foldrNatF :: (HVectorF v) => (forall a. f a -> b -> b) -> b -> v f -> b

-- | Left fold over heterogeneous vector
foldlNatF :: (HVectorF v) => (forall a. b -> f a -> b) -> b -> v f -> b

-- | Apply monadic action to every element in the vector
mapM_ :: (HVector v, ArityC c (Elems v), Applicative f) => Proxy c -> (forall a. c a => a -> f ()) -> v -> f ()

-- | Unfold vector.
unfoldr :: (HVector v, ArityC c (Elems v)) => Proxy c -> (forall a. c a => b -> (a, b)) -> b -> v

-- | Unfold vector.
unfoldrF :: (HVectorF v, ArityC c (ElemsF v)) => Proxy c -> (forall a. c a => b -> (f a, b)) -> b -> v f

-- | Replicate polymorphic value n times. Concrete instance for every
--   element is determined by their respective types.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Vector.HFixed as H
--   
--   &gt;&gt;&gt; H.replicate (Proxy :: Proxy Monoid) mempty :: ((),String)
--   ((),"")
--   </pre>
replicate :: (HVector v, ArityC c (Elems v)) => Proxy c -> (forall x. c x => x) -> v

-- | Replicate monadic action n times.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Vector.HFixed as H
--   
--   &gt;&gt;&gt; H.replicateM (Proxy :: Proxy Read) (fmap read getLine) :: IO (Int,Char)
--   &gt; 12
--   &gt; 'a'
--   (12,'a')
--   </pre>
replicateM :: (HVector v, Applicative f, ArityC c (Elems v)) => Proxy c -> (forall a. c a => f a) -> f v
replicateF :: (HVectorF v, ArityC c (ElemsF v)) => Proxy c -> (forall a. c a => f a) -> v f
replicateNatF :: (HVectorF v, Arity (ElemsF v)) => (forall a. f a) -> v f

-- | Zip two heterogeneous vectors
zipWith :: (HVector v, ArityC c (Elems v)) => Proxy c -> (forall a. c a => a -> a -> a) -> v -> v -> v

-- | Zip two heterogeneous vectors
zipWithF :: (HVectorF v, ArityC c (ElemsF v)) => Proxy c -> (forall a. c a => f a -> g a -> h a) -> v f -> v g -> v h

-- | Zip two heterogeneous vectors
zipWithNatF :: (HVectorF v) => (forall a. f a -> g a -> h a) -> v f -> v g -> v h
zipFold :: (HVector v, ArityC c (Elems v), Monoid m) => Proxy c -> (forall a. c a => a -> a -> m) -> v -> v -> m
zipFoldF :: (HVectorF v, ArityC c (ElemsF v), Monoid m) => Proxy c -> (forall a. c a => f a -> f a -> m) -> v f -> v f -> m

-- | Convert heterogeneous vector to homogeneous
monomorphize :: (HVector v, Peano n ~ Len (Elems v), ArityC c (Elems v)) => Proxy c -> (forall a. c a => a -> x) -> v -> ContVec n x

-- | Convert heterogeneous vector to homogeneous
monomorphizeF :: (HVectorF v, Peano n ~ Len (ElemsF v), ArityC c (ElemsF v)) => Proxy c -> (forall a. c a => f a -> x) -> v f -> ContVec n x

-- | Apply natural transformation to every element of the tuple.
mapNat :: (HVectorF v) => (forall a. f a -> g a) -> v f -> v g

-- | Sequence effects for every element in the vector
sequence :: (Applicative f, HVectorF v, HVector w, ElemsF v ~ Elems w) => v f -> f w

-- | Sequence effects for every element in the vector
sequence_ :: (Applicative f, HVectorF v) => v f -> f ()

-- | Sequence effects for every element in the vector
sequenceF :: (Applicative f, HVectorF v) => v (f `Compose` g) -> f (v g)

-- | Wrap every value in the vector into type constructor.
wrap :: (HVector v, HVectorF w, Elems v ~ ElemsF w) => (forall a. a -> f a) -> v -> w f

-- | Unwrap every value in the vector from the type constructor.
unwrap :: (HVectorF v, HVector w, ElemsF v ~ Elems w) => (forall a. f a -> a) -> v f -> w

-- | Analog of <i>distribute</i> from <i>Distributive</i> type class.
distribute :: (Functor f, HVector v, HVectorF w, Elems v ~ ElemsF w) => f v -> w f

-- | Analog of <i>distribute</i> from <i>Distributive</i> type class.
distributeF :: (Functor f, HVectorF v) => f (v g) -> v (f `Compose` g)

-- | Generic equality for heterogeneous vectors
eq :: (HVector v, ArityC Eq (Elems v)) => v -> v -> Bool

-- | Generic comparison for heterogeneous vectors
compare :: (HVector v, ArityC Ord (Elems v)) => v -> v -> Ordering

-- | Reduce vector to normal form
rnf :: (HVector v, ArityC NFData (Elems v)) => v -> ()


-- | Heterogeneous vector parametric in its elements
module Data.Vector.HFixed.HVec

-- | Generic heterogeneous vector
data HVec (xs :: [*])

-- | Heterogeneous vector parametrized by common type constructor.
data HVecF (xs :: [*]) (f :: * -> *)
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.HVector (Data.Vector.HFixed.HVec.HVec xs)
instance Data.Vector.HFixed.Class.ArityC GHC.Show.Show xs => GHC.Show.Show (Data.Vector.HFixed.HVec.HVec xs)
instance Data.Vector.HFixed.Class.ArityC GHC.Classes.Eq xs => GHC.Classes.Eq (Data.Vector.HFixed.HVec.HVec xs)
instance (Data.Vector.HFixed.Class.ArityC GHC.Classes.Ord xs, Data.Vector.HFixed.Class.ArityC GHC.Classes.Eq xs) => GHC.Classes.Ord (Data.Vector.HFixed.HVec.HVec xs)
instance Data.Vector.HFixed.Class.ArityC GHC.Base.Monoid xs => GHC.Base.Monoid (Data.Vector.HFixed.HVec.HVec xs)
instance Data.Vector.HFixed.Class.ArityC Control.DeepSeq.NFData xs => Control.DeepSeq.NFData (Data.Vector.HFixed.HVec.HVec xs)
instance Data.Vector.HFixed.Class.Arity xs => Data.Vector.HFixed.Class.HVectorF (Data.Vector.HFixed.HVec.HVecF xs)
instance (Data.Functor.Classes.Show1 f, Data.Vector.HFixed.Class.ArityC GHC.Show.Show xs) => GHC.Show.Show (Data.Vector.HFixed.HVec.HVecF xs f)
instance (Data.Functor.Classes.Eq1 f, Data.Vector.HFixed.Class.ArityC GHC.Classes.Eq xs) => GHC.Classes.Eq (Data.Vector.HFixed.HVec.HVecF xs f)
instance (Data.Functor.Classes.Ord1 f, Data.Vector.HFixed.Class.ArityC GHC.Classes.Eq xs, Data.Vector.HFixed.Class.ArityC GHC.Classes.Ord xs) => GHC.Classes.Ord (Data.Vector.HFixed.HVec.HVecF xs f)
