{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Vector.HFixed (
HVector(..)
, tupleSize
, HVectorF(..)
, tupleSizeF
, ContVec
, ContVecF(..)
, asCVec
, asCVecF
, mk0
, mk1
, mk2
, mk3
, mk4
, mk5
, unfoldr
, replicate
, replicateM
, convert
, head
, tail
, cons
, concat
, ValueAt
, Index
, index
, set
, element
, elementCh
, tyLookup
, tyLookupF
, foldr
, foldl
, mapM_
, zipWith
, zipFold
, eq
, compare
, rnf
, mk0F
, mk1F
, mk2F
, mk3F
, mk4F
, mk5F
, unfoldrF
, replicateF
, replicateNatF
, wrap
, unwrap
, monomorphize
, monomorphizeF
, map
, mapNat
, sequence
, sequence_
, sequenceF
, distribute
, distributeF
, foldrF
, foldlF
, foldrNatF
, foldlNatF
, zipWithF
, zipWithNatF
, zipFoldF
, Arity
, ArityC
, Proxy(..)
) where
import Control.Applicative (Applicative(..),(<$>))
import qualified Control.DeepSeq as NF
import Data.Coerce (coerce)
import Data.Functor.Compose (Compose(..))
import Data.Functor.Identity (Identity(..))
import Data.Monoid (Monoid,All(..))
import Prelude ( Functor(..),Eq(..),Ord,Bool,Ordering
, id,(.),($),seq)
import qualified Prelude
import Data.Vector.HFixed.Class hiding (cons,consF)
import Data.Vector.Fixed.Cont (Peano)
import qualified Data.Vector.Fixed as F
import qualified Data.Vector.HFixed.Cont as C
asCVec :: ContVec xs -> ContVec xs
asCVec = id
asCVecF :: ContVecF f xs -> ContVecF f xs
asCVecF = id
convert :: (HVector v, HVector w, Elems v ~ Elems w)
=> v -> w
{-# INLINE convert #-}
convert v = inspect v construct
tail :: (HVector v, HVector w, (a : Elems w) ~ Elems v)
=> v -> w
{-# INLINE tail #-}
tail = C.vector . C.tail . C.cvec
head :: (HVector v, Elems v ~ (a : as), Arity as)
=> v -> a
{-# INLINE head #-}
head = C.head . C.cvec
cons :: (HVector v, HVector w, Elems w ~ (a : Elems v))
=> a -> v -> w
{-# INLINE cons #-}
cons a = C.vector . C.cons a . C.cvec
concat :: ( HVector v, HVector u, HVector w
, Elems w ~ (Elems v ++ Elems u)
)
=> v -> u -> w
concat v u = C.vector $ C.concat (C.cvec v) (C.cvec u)
{-# INLINE concat #-}
index
:: forall n v proxy. (Index (Peano n) (Elems v), HVector v)
=> proxy n
-> v
-> ValueAt (Peano n) (Elems v)
{-# INLINE index #-}
index _ v = C.index (C.cvec v) (Proxy @(Peano n))
set :: forall n v proxy. (Index (Peano n) (Elems v), HVector v)
=> proxy n
-> ValueAt (Peano n) (Elems v)
-> v
-> v
{-# INLINE set #-}
set _ x = C.vector
. C.set (Proxy @(Peano n)) x
. C.cvec
element :: forall n v proxy.
( Index (Peano n) (Elems v)
, HVector v
)
=> proxy n
-> Lens' v (ValueAt (Peano n) (Elems v))
{-# INLINE element #-}
element _ f v = inspect v
$ lensF (Proxy @(Peano n)) f construct
elementCh :: forall n v w a b proxy.
( Index (Peano n) (Elems v)
, ValueAt (Peano n) (Elems v) ~ a
, HVector v
, HVector w
, Elems w ~ NewElems (Peano n) (Elems v) b
)
=> proxy n
-> Lens v w a b
{-# INLINE elementCh #-}
elementCh _ f v = inspect v
$ lensChF (Proxy @(Peano n)) f construct
tyLookup :: (HVector v, TyLookup a (Elems v)) => v -> a
tyLookup = C.tyLookup . C.cvec
{-# INLINE tyLookup #-}
tyLookupF :: (HVectorF v, TyLookup a (ElemsF v)) => v f -> f a
tyLookupF = C.tyLookupF . C.cvecF
{-# INLINE tyLookupF #-}
foldr :: (HVector v, ArityC c (Elems v))
=> Proxy c -> (forall a. c a => a -> b -> b) -> b -> v -> b
{-# INLINE foldr #-}
foldr c f b0 = C.foldrF c (\(Identity a) b -> f a b) b0 . C.cvec
foldl :: (HVector v, ArityC c (Elems v))
=> Proxy c -> (forall a. c a => b -> a -> b) -> b -> v -> b
{-# INLINE foldl #-}
foldl c f b0 = C.foldlF c (\b (Identity a) -> f b a) b0 . C.cvec
foldrF :: (HVectorF v, ArityC c (ElemsF v))
=> Proxy c -> (forall a. c a => f a -> b -> b) -> b -> v f -> b
{-# INLINE foldrF #-}
foldrF c f b0 = C.foldrF c f b0 . C.cvecF
foldlF :: (HVectorF v, ArityC c (ElemsF v))
=> Proxy c -> (forall a. c a => b -> f a -> b) -> b -> v f -> b
{-# INLINE foldlF #-}
foldlF c f b0 = C.foldlF c f b0 . C.cvecF
foldrNatF :: (HVectorF v)
=> (forall a. f a -> b -> b) -> b -> v f -> b
{-# INLINE foldrNatF #-}
foldrNatF f b0 = C.foldrNatF f b0 . C.cvecF
foldlNatF :: (HVectorF v)
=> (forall a. b -> f a -> b) -> b -> v f -> b
{-# INLINE foldlNatF #-}
foldlNatF f b0 = C.foldlNatF f b0 . C.cvecF
mapM_ :: (HVector v, ArityC c (Elems v), Applicative f)
=> Proxy c -> (forall a. c a => a -> f ()) -> v -> f ()
{-# INLINE mapM_ #-}
mapM_ c f = foldl c (\m a -> m *> f a) (pure ())
unfoldr :: (HVector v, ArityC c (Elems v))
=> Proxy c -> (forall a. c a => b -> (a,b)) -> b -> v
{-# INLINE unfoldr #-}
unfoldr c f = C.vector . C.unfoldrF c (\b -> let (a,b') = f b in (Identity a, b'))
unfoldrF :: (HVectorF v, ArityC c (ElemsF v))
=> Proxy c -> (forall a. c a => b -> (f a,b)) -> b -> v f
{-# INLINE unfoldrF #-}
unfoldrF c f = C.vectorF . C.unfoldrF c f
mk0 :: forall v. (HVector v, Elems v ~ '[]) => v
mk0 = coerce (construct :: Fun '[] v)
{-# INLINE mk0 #-}
mk1 :: forall v a. (HVector v, Elems v ~ '[a])
=> a -> v
mk1 = coerce (construct :: Fun '[a] v)
{-# INLINE mk1 #-}
mk2 :: forall v a b. (HVector v, Elems v ~ '[a,b])
=> a -> b -> v
mk2 = coerce (construct :: Fun '[a,b] v)
{-# INLINE mk2 #-}
mk3 :: forall v a b c. (HVector v, Elems v ~ '[a,b,c])
=> a -> b -> c -> v
mk3 = coerce (construct :: Fun '[a,b,c] v)
{-# INLINE mk3 #-}
mk4 :: forall v a b c d. (HVector v, Elems v ~ '[a,b,c,d])
=> a -> b -> c -> d -> v
mk4 = coerce (construct :: Fun '[a,b,c,d] v)
{-# INLINE mk4 #-}
mk5 :: forall v a b c d e. (HVector v, Elems v ~ '[a,b,c,d,e])
=> a -> b -> c -> d -> e -> v
mk5 = coerce (construct :: Fun '[a,b,c,d,e] v)
{-# INLINE mk5 #-}
mk0F :: forall f v. (HVectorF v, ElemsF v ~ '[]) => v f
mk0F = coerce (constructF :: TFun f '[] (v f))
{-# INLINE mk0F #-}
mk1F :: forall f v a. (HVectorF v, ElemsF v ~ '[a])
=> f a -> v f
mk1F = coerce (constructF :: TFun f '[a] (v f))
{-# INLINE mk1F #-}
mk2F :: forall f v a b. (HVectorF v, ElemsF v ~ '[a,b])
=> f a -> f b -> v f
mk2F = coerce (constructF :: TFun f '[a,b] (v f))
{-# INLINE mk2F #-}
mk3F :: forall f v a b c. (HVectorF v, ElemsF v ~ '[a,b,c])
=> f a -> f b -> f c -> v f
mk3F = coerce (constructF :: TFun f '[a,b,c] (v f))
{-# INLINE mk3F #-}
mk4F :: forall f v a b c d. (HVectorF v, ElemsF v ~ '[a,b,c,d])
=> f a -> f b -> f c -> f d -> v f
mk4F = coerce (constructF :: TFun f '[a,b,c,d] (v f))
{-# INLINE mk4F #-}
mk5F :: forall f v a b c d e. (HVectorF v, ElemsF v ~ '[a,b,c,d,e])
=> f a -> f b -> f c -> f d -> f e -> v f
mk5F = coerce (constructF :: TFun f '[a,b,c,d,e] (v f))
{-# INLINE mk5F #-}
map :: (HVectorF v, ArityC c (ElemsF v))
=> Proxy c -> (forall a. c a => f a -> g a) -> v f -> v g
{-# INLINE map #-}
map cls f = C.vectorF . C.map cls f . C.cvecF
mapNat :: (HVectorF v)
=> (forall a. f a -> g a) -> v f -> v g
{-# INLINE mapNat #-}
mapNat f = C.vectorF . C.mapNat f . C.cvecF
sequence
:: ( Applicative f, HVectorF v, HVector w, ElemsF v ~ Elems w )
=> v f -> f w
{-# INLINE sequence #-}
sequence
= fmap C.vector
. C.sequenceF
. C.mapNat (Compose . fmap Identity)
. C.cvecF
sequence_ :: (Applicative f, HVectorF v) => v f -> f ()
{-# INLINE sequence_ #-}
sequence_ = foldlNatF (\m a -> m <* a) (pure ())
sequenceF :: ( Applicative f, HVectorF v) => v (f `Compose` g) -> f (v g)
{-# INLINE sequenceF #-}
sequenceF v = C.vectorF <$> C.sequenceF (C.cvecF v)
wrap :: ( HVector v, HVectorF w, Elems v ~ ElemsF w )
=> (forall a. a -> f a) -> v -> w f
{-# INLINE wrap #-}
wrap f = C.vectorF . C.mapNat (f . runIdentity) . C.cvec
unwrap :: ( HVectorF v, HVector w, ElemsF v ~ Elems w )
=> (forall a. f a -> a) -> v f -> w
{-# INLINE unwrap #-}
unwrap f = C.vector . C.mapNat (Identity . f) . C.cvecF
distribute
:: ( Functor f, HVector v, HVectorF w, Elems v ~ ElemsF w )
=> f v -> w f
{-# INLINE distribute #-}
distribute
= C.vectorF
. mapNat (fmap runIdentity . getCompose)
. C.distributeF
. fmap C.cvec
distributeF
:: ( Functor f, HVectorF v)
=> f (v g) -> v (f `Compose` g)
{-# INLINE distributeF #-}
distributeF = C.vectorF . C.distributeF . fmap C.cvecF
replicate :: (HVector v, ArityC c (Elems v))
=> Proxy c -> (forall x. c x => x) -> v
{-# INLINE replicate #-}
replicate c x = C.vector $ C.replicateF c (Identity x)
replicateM :: (HVector v, Applicative f, ArityC c (Elems v))
=> Proxy c -> (forall a. c a => f a) -> f v
{-# INLINE replicateM #-}
replicateM c x
= fmap C.vector
$ C.sequenceF
$ C.replicateF c (Compose $ fmap Identity x)
replicateNatF :: (HVectorF v, Arity (ElemsF v))
=> (forall a. f a) -> v f
{-# INLINE replicateNatF #-}
replicateNatF x = C.vectorF $ C.replicateNatF x
replicateF :: (HVectorF v, ArityC c (ElemsF v))
=> Proxy c -> (forall a. c a => f a) -> v f
{-# INLINE replicateF #-}
replicateF c x = C.vectorF $ C.replicateF c x
zipWith :: (HVector v, ArityC c (Elems v))
=> Proxy c -> (forall a. c a => a -> a -> a) -> v -> v -> v
{-# INLINE zipWith #-}
zipWith c f v u
= C.vector
$ C.zipWithF c (\(Identity a) (Identity b) -> Identity (f a b)) (C.cvec v) (C.cvec u)
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
{-# INLINE zipWithF #-}
zipWithF c f v u
= C.vectorF $ C.zipWithF c f (C.cvecF v) (C.cvecF u)
zipWithNatF :: (HVectorF v)
=> (forall a. f a -> g a -> h a) -> v f -> v g -> v h
{-# INLINE zipWithNatF #-}
zipWithNatF f v u
= C.vectorF $ C.zipWithNatF f (C.cvecF v) (C.cvecF u)
zipFold :: (HVector v, ArityC c (Elems v), Monoid m)
=> Proxy c -> (forall a. c a => a -> a -> m) -> v -> v -> m
{-# INLINE zipFold #-}
zipFold c f v u
= C.zipFoldF c (\(Identity a) (Identity b) -> f a b) (C.cvec v) (C.cvec u)
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
{-# INLINE zipFoldF #-}
zipFoldF c f v u
= C.zipFoldF c f (C.cvecF v) (C.cvecF u)
monomorphize :: ( HVector v
, Peano n ~ Len (Elems v)
, ArityC c (Elems v))
=> Proxy c -> (forall a. c a => a -> x)
-> v -> F.ContVec n x
{-# INLINE monomorphize #-}
monomorphize c f = C.monomorphizeF c (f . runIdentity) . C.cvec
monomorphizeF :: ( HVectorF v
, Peano n ~ Len (ElemsF v)
, ArityC c (ElemsF v)
)
=> Proxy c -> (forall a. c a => f a -> x)
-> v f -> F.ContVec n x
{-# INLINE monomorphizeF #-}
monomorphizeF c f = C.monomorphizeF c f . C.cvecF
eq :: (HVector v, ArityC Eq (Elems v)) => v -> v -> Bool
eq v u = getAll $ zipFold (Proxy :: Proxy Eq) (\x y -> All (x == y)) v u
{-# INLINE eq #-}
compare :: (HVector v, ArityC Ord (Elems v)) => v -> v -> Ordering
compare = zipFold (Proxy :: Proxy Ord) Prelude.compare
{-# INLINE compare #-}
rnf :: (HVector v, ArityC NF.NFData (Elems v)) => v -> ()
rnf = foldl (Proxy :: Proxy NF.NFData) (\r a -> NF.rnf a `seq` r) ()
{-# INLINE rnf #-}