module Data.Vector.Fixed.Cont (
PeanoNum(..)
, Peano
, Add
, Fn
, Fun(..)
, Arity
, ArityPeano(..)
, arity
, apply
, applyM
, constFun
, curryFirst
, uncurryFirst
, curryLast
, curryMany
, apLast
, shuffleFun
, withFun
, Dim
, Vector(..)
, VectorN
, length
, ContVec(..)
, CVecPeano(..)
, consPeano
, toContVec
, runContVec
, cvec
, fromList
, fromList'
, fromListM
, toList
, replicate
, replicateM
, generate
, generateM
, unfoldr
, basis
, empty
, cons
, consV
, snoc
, concat
, mk1
, mk2
, mk3
, mk4
, mk5
, map
, imap
, mapM
, imapM
, mapM_
, imapM_
, scanl
, scanl1
, sequence
, sequence_
, distribute
, collect
, tail
, reverse
, zipWith
, zipWith3
, izipWith
, izipWith3
, zipWithM
, zipWithM_
, izipWithM
, izipWithM_
, head
, index
, element
, vector
, foldl
, foldl1
, foldr
, ifoldl
, ifoldr
, foldM
, ifoldM
, sum
, minimum
, maximum
, and
, or
, all
, any
, find
, gfoldl
, gunfold
) where
import Control.Applicative ((<|>))
import Data.Coerce
import Data.Complex (Complex(..))
import Data.Data (Data)
import Data.Functor.Identity (Identity(..))
import Data.Typeable (Proxy(..))
import qualified Data.Foldable as F
import qualified Data.Traversable as F
import Unsafe.Coerce (unsafeCoerce)
import GHC.TypeLits
import Prelude hiding ( replicate,map,zipWith,zipWith3,maximum,minimum,and,or,any,all
, foldl,foldr,foldl1,length,sum,reverse,scanl,scanl1
, head,tail,mapM,mapM_,sequence,sequence_,concat
)
data PeanoNum = Z
| S PeanoNum
type family Peano (n :: Nat) :: PeanoNum where
Peano 0 = 'Z
Peano n = 'S (Peano (n 1))
type family Add (n :: PeanoNum) (m :: PeanoNum) :: PeanoNum where
Add 'Z n = n
Add ('S n) k = 'S (Add n k)
type family Fn (n :: PeanoNum) (a :: *) (b :: *) where
Fn 'Z a b = b
Fn ('S n) a b = a -> Fn n a b
newtype Fun n a b = Fun { unFun :: Fn n a b }
instance ArityPeano n => Functor (Fun n a) where
fmap f fun
= accum (\(T_Flip g) a -> T_Flip (curryFirst g a))
(\(T_Flip x) -> f (unFun x))
(T_Flip fun)
instance ArityPeano n => Applicative (Fun n a) where
pure x = accum (\Proxy _ -> Proxy)
(\Proxy -> x)
Proxy
(Fun f0 :: Fun n a (p -> q)) <*> (Fun g0 :: Fun n a p)
= accum (\(T_ap f g) a -> T_ap (f a) (g a))
(\(T_ap f g) -> f g)
(T_ap f0 g0 :: T_ap a (p -> q) p n)
instance ArityPeano n => Monad (Fun n a) where
return = pure
f >>= g = shuffleFun g <*> f
data T_ap a b c n = T_ap (Fn n a b) (Fn n a c)
type Arity n = ( ArityPeano (Peano n)
, KnownNat n
, Peano (n+1) ~ 'S (Peano n)
)
class ArityPeano n where
accum :: (forall k. t ('S k) -> a -> t k)
-> (t 'Z -> b)
-> t n
-> Fun n a b
applyFun :: (forall k. t ('S k) -> (a, t k))
-> t n
-> (CVecPeano n a, t 'Z)
applyFunM :: Applicative f
=> (forall k. t ('S k) -> (f a, t k))
-> t n
-> (f (CVecPeano n a), t 'Z)
reverseF :: Fun n a b -> Fun n a b
gunfoldF :: (Data a)
=> (forall b x. Data b => c (b -> x) -> c x)
-> T_gunfold c r a n -> c r
newtype T_gunfold c r a n = T_gunfold (c (Fn n a r))
apply :: Arity n
=> (forall k. t ('S k) -> (a, t k))
-> t (Peano n)
-> ContVec n a
apply step z = toContVec $ fst (applyFun step z)
applyM :: (Applicative f, Arity n)
=> (forall k. t ('S k) -> (f a, t k))
-> t (Peano n)
-> f (ContVec n a)
applyM f t = fmap toContVec $ fst $ applyFunM f t
arity :: KnownNat n => proxy n -> Int
arity = fromIntegral . natVal
instance ArityPeano 'Z where
accum _ g t = Fun $ g t
applyFun _ t = (CVecPeano unFun, t)
applyFunM _ t = (pure (CVecPeano unFun), t)
reverseF = id
gunfoldF _ (T_gunfold c) = c
instance ArityPeano n => ArityPeano ('S n) where
accum f g t = Fun $ \a -> unFun $ accum f g (f t a)
applyFun f t = let (a,t') = f t
(v,tZ) = applyFun f t'
in (consPeano a v, tZ)
applyFunM f t = let (a,t') = f t
(vec,t0) = applyFunM f t'
in (consPeano <$> a <*> vec, t0)
reverseF f = Fun $ \a -> unFun (reverseF $ apLast f a)
gunfoldF f c = gunfoldF f (apGunfold f c)
apGunfold :: Data a
=> (forall b x. Data b => c (b -> x) -> c x)
-> T_gunfold c r a ('S n)
-> T_gunfold c r a n
apGunfold f (T_gunfold c) = T_gunfold $ f c
newtype T_Flip a b n = T_Flip (Fun n a b)
constFun :: Fun n a b -> Fun ('S n) a b
constFun (Fun f) = Fun $ \_ -> f
curryFirst :: Fun ('S n) a b -> a -> Fun n a b
curryFirst = coerce
uncurryFirst :: (a -> Fun n a b) -> Fun ('S n) a b
uncurryFirst = coerce
curryLast :: ArityPeano n => Fun ('S n) a b -> Fun n a (a -> b)
curryLast = unsafeCoerce
curryMany :: forall n k a b. ArityPeano n
=> Fun (Add n k) a b -> Fun n a (Fun k a b)
curryMany = unsafeCoerce
apLast :: ArityPeano n => Fun ('S n) a b -> a -> Fun n a b
apLast f x = fmap ($ x) $ curryLast f
withFun :: (Fun n a b -> Fun n a b) -> Fun ('S n) a b -> Fun ('S n) a b
withFun f fun = Fun $ \a -> unFun $ f $ curryFirst fun a
shuffleFun :: ArityPeano n
=> (b -> Fun n a r) -> Fun n a (b -> r)
shuffleFun f0
= accum (\(T_shuffle f) a -> T_shuffle $ \x -> f x a)
(\(T_shuffle f) -> f)
(T_shuffle (fmap unFun f0))
newtype T_shuffle x a r n = T_shuffle (x -> Fn n a r)
type family Dim (v :: * -> *) :: Nat
class Arity (Dim v) => Vector v a where
construct :: Fun (Peano (Dim v)) a (v a)
inspect :: v a -> Fun (Peano (Dim v)) a b -> b
basicIndex :: v a -> Int -> a
basicIndex v i = index i (cvec v)
class (Vector (v n) a, Dim (v n) ~ n) => VectorN v n a
length :: forall v a. KnownNat (Dim v) => v a -> Int
length _ = arity (Proxy :: Proxy (Dim v))
newtype ContVec n a = ContVec (forall r. Fun (Peano n) a r -> r)
type instance Dim (ContVec n) = n
newtype CVecPeano n a = CVecPeano (forall r. Fun n a r -> r)
consPeano :: a -> CVecPeano n a -> CVecPeano ('S n) a
consPeano a (CVecPeano cont) = CVecPeano $ \f -> cont $ curryFirst f a
toContVec :: CVecPeano (Peano n) a -> ContVec n a
toContVec = coerce
instance Arity n => Vector (ContVec n) a where
construct = accum
(\(T_mkN f) a -> T_mkN (f . consPeano a))
(\(T_mkN f) -> toContVec $ f (CVecPeano unFun))
(T_mkN id)
inspect (ContVec c) f = c f
newtype T_mkN n_tot a n = T_mkN (CVecPeano n a -> CVecPeano n_tot a)
instance Arity n => VectorN ContVec n a
instance (Arity n) => Functor (ContVec n) where
fmap = map
instance (Arity n) => Applicative (ContVec n) where
pure = replicate
(<*>) = zipWith ($)
instance (Arity n) => F.Foldable (ContVec n) where
foldr = foldr
instance (Arity n) => F.Traversable (ContVec n) where
sequenceA v = inspect v $ sequenceAF construct
sequenceAF :: forall f n a b. (Applicative f, ArityPeano n)
=> Fun n a b -> Fun n (f a) (f b)
sequenceAF (Fun f0)
= accum (\(T_sequenceA f) a -> T_sequenceA (f <*> a))
(\(T_sequenceA f) -> f)
(T_sequenceA (pure f0) :: T_sequenceA f a b n)
newtype T_sequenceA f a b n = T_sequenceA (f (Fn n a b))
cvec :: (Vector v a, Dim v ~ n) => v a -> ContVec n a
cvec v = ContVec (inspect v)
empty :: ContVec 0 a
empty = ContVec (\(Fun r) -> r)
fromList :: Arity n => [a] -> ContVec n a
fromList xs =
apply step (Const xs)
where
step (Const [] ) = error "Data.Vector.Fixed.Cont.fromList: too few elements"
step (Const (a:as)) = (a, Const as)
fromList' :: forall n a. Arity n => [a] -> ContVec n a
fromList' xs =
let step (Const [] ) = error "Data.Vector.Fixed.Cont.fromList': too few elements"
step (Const (a:as)) = (a, Const as)
in case applyFun step (Const xs :: Const [a] (Peano n)) of
(v,Const []) -> toContVec v
_ -> error "Data.Vector.Fixed.Cont.fromList': too many elements"
fromListM :: forall n a. Arity n => [a] -> Maybe (ContVec n a)
fromListM xs = case applyFunM step (Const xs :: Const [a] (Peano n)) of
(Just v, Const []) -> Just (toContVec v)
_ -> Nothing
where
step (Const [] ) = (Nothing, Const [])
step (Const (a:as)) = (Just a , Const as)
toList :: (Arity n) => ContVec n a -> [a]
toList = foldr (:) []
replicate :: (Arity n) => a -> ContVec n a
replicate a = apply (\Proxy -> (a, Proxy)) Proxy
replicateM :: (Arity n, Applicative f) => f a -> f (ContVec n a)
replicateM act
= applyM (\Proxy -> (act, Proxy)) Proxy
generate :: (Arity n) => (Int -> a) -> ContVec n a
generate f =
apply (\(Const n) -> (f n, Const (n + 1))) (Const 0)
generateM :: (Applicative f, Arity n) => (Int -> f a) -> f (ContVec n a)
generateM f =
applyM (\(Const n) -> (f n, Const (n + 1))) (Const 0)
unfoldr :: Arity n => (b -> (a,b)) -> b -> ContVec n a
unfoldr f b0 =
apply (\(Const b) -> let (a,b') = f b in (a, Const b'))
(Const b0)
basis :: (Num a, Arity n) => Int -> ContVec n a
basis n0 =
apply (\(Const n) -> (if n == 0 then 1 else 0, Const (n 1)))
(Const n0)
mk1 :: a -> ContVec 1 a
mk1 a1 = ContVec $ \(Fun f) -> f a1
mk2 :: a -> a -> ContVec 2 a
mk2 a1 a2 = ContVec $ \(Fun f) -> f a1 a2
mk3 :: a -> a -> a -> ContVec 3 a
mk3 a1 a2 a3 = ContVec $ \(Fun f) -> f a1 a2 a3
mk4 :: a -> a -> a -> a -> ContVec 4 a
mk4 a1 a2 a3 a4 = ContVec $ \(Fun f) -> f a1 a2 a3 a4
mk5 :: a -> a -> a -> a -> a -> ContVec 5 a
mk5 a1 a2 a3 a4 a5 = ContVec $ \(Fun f) -> f a1 a2 a3 a4 a5
map :: (Arity n) => (a -> b) -> ContVec n a -> ContVec n b
map = imap . const
imap :: (Arity n) => (Int -> a -> b) -> ContVec n a -> ContVec n b
imap f (ContVec contA) = ContVec $
contA . imapF f
mapM :: (Arity n, Applicative f) => (a -> f b) -> ContVec n a -> f (ContVec n b)
mapM = imapM . const
imapM :: (Arity n, Applicative f)
=> (Int -> a -> f b) -> ContVec n a -> f (ContVec n b)
imapM f v
= inspect v
$ imapMF f construct
mapM_ :: (Arity n, Applicative f) => (a -> f b) -> ContVec n a -> f ()
mapM_ f = foldl (\m a -> m *> f a *> pure ()) (pure ())
imapM_ :: (Arity n, Applicative f) => (Int -> a -> f b) -> ContVec n a -> f ()
imapM_ f = ifoldl (\m i a -> m *> f i a *> pure ()) (pure ())
imapMF :: (ArityPeano n, Applicative f)
=> (Int -> a -> f b) -> Fun n b r -> Fun n a (f r)
imapMF f (Fun funB) =
accum (\(T_mapM i m) a -> T_mapM (i+1) $ ($) <$> m <*> f i a)
(\(T_mapM _ m) -> m)
(T_mapM 0 (pure funB))
data T_mapM a m r n = T_mapM Int (m (Fn n a r))
imapF :: ArityPeano n
=> (Int -> a -> b) -> Fun n b r -> Fun n a r
imapF f (Fun funB) =
accum (\(T_map i g) b -> T_map (i+1) (g (f i b)))
(\(T_map _ r) -> r)
( T_map 0 funB)
data T_map a r n = T_map Int (Fn n a r)
scanl :: (Arity n) => (b -> a -> b) -> b -> ContVec n a -> ContVec (n+1) b
scanl f b0 (ContVec cont) = ContVec $
cont . scanlF f b0
scanl1 :: (Arity n) => (a -> a -> a) -> ContVec n a -> ContVec n a
scanl1 f (ContVec cont) = ContVec $
cont . scanl1F f
scanlF :: forall n a b r. (ArityPeano n) => (b -> a -> b) -> b -> Fun ('S n) b r -> Fun n a r
scanlF f b0 (Fun fun0)
= accum step fini start
where
step :: forall k. T_scanl r b ('S k) -> a -> T_scanl r b k
step (T_scanl b fn) a = let b' = f b a in T_scanl b' (fn b')
fini (T_scanl _ r) = r
start = T_scanl b0 (fun0 b0) :: T_scanl r b n
scanl1F :: forall n a r. (ArityPeano n) => (a -> a -> a) -> Fun n a r -> Fun n a r
scanl1F f (Fun fun0) = accum step fini start
where
step :: forall k. T_scanl1 r a ('S k) -> a -> T_scanl1 r a k
step (T_scanl1 Nothing fn) a = T_scanl1 (Just a) (fn a)
step (T_scanl1 (Just x) fn) a = let a' = f x a in T_scanl1 (Just a') (fn a')
fini (T_scanl1 _ r) = r
start = T_scanl1 Nothing fun0 :: T_scanl1 r a n
data T_scanl r a n = T_scanl a (Fn n a r)
data T_scanl1 r a n = T_scanl1 (Maybe a) (Fn n a r)
sequence :: (Arity n, Applicative f) => ContVec n (f a) -> f (ContVec n a)
sequence = mapM id
sequence_ :: (Arity n, Applicative f) => ContVec n (f a) -> f ()
sequence_ = mapM_ id
distribute :: (Functor f, Arity n) => f (ContVec n a) -> ContVec n (f a)
distribute f0
= apply step start
where
step (Const f) = ( fmap (\(x:_) -> x) f
, Const $ fmap (\(_:x) -> x) f)
start = Const (fmap toList f0)
collect :: (Functor f, Arity n) => (a -> ContVec n b) -> f a -> ContVec n (f b)
collect f = distribute . fmap f
tail :: Arity n => ContVec (n+1) a -> ContVec n a
tail (ContVec cont) = ContVec $ \f -> cont $ constFun f
cons :: Arity n => a -> ContVec n a -> ContVec (n+1) a
cons a (ContVec cont) = ContVec $ \f -> cont $ curryFirst f a
consV :: Arity n => ContVec 1 a -> ContVec n a -> ContVec (n+1) a
consV (ContVec cont1) (ContVec cont)
= ContVec $ \f -> cont $ curryFirst f $ cont1 $ Fun id
snoc :: Arity n => a -> ContVec n a -> ContVec (n+1) a
snoc a (ContVec cont) = ContVec $ \f -> cont $ apLast f a
concat :: ( Arity n
, Arity k
, Arity (n + k)
, Peano (n + k) ~ Add (Peano n) (Peano k)
)
=> ContVec n a -> ContVec k a -> ContVec (n + k) a
concat v u = inspect u
$ inspect v
$ curryMany construct
reverse :: Arity n => ContVec n a -> ContVec n a
reverse (ContVec cont) = ContVec $ cont . reverseF
zipWith :: (Arity n) => (a -> b -> c)
-> ContVec n a -> ContVec n b -> ContVec n c
zipWith = izipWith . const
zipWith3 :: (Arity n) => (a -> b -> c -> d)
-> ContVec n a -> ContVec n b -> ContVec n c -> ContVec n d
zipWith3 f v1 v2 v3 = zipWith (\a (b, c) -> f a b c) v1 (zipWith (,) v2 v3)
izipWith :: (Arity n) => (Int -> a -> b -> c)
-> ContVec n a -> ContVec n b -> ContVec n c
izipWith f vecA vecB = ContVec $ \funC ->
inspect vecB
$ inspect vecA
$ izipWithF f funC
izipWith3 :: (Arity n) => (Int -> a -> b -> c -> d)
-> ContVec n a -> ContVec n b -> ContVec n c -> ContVec n d
izipWith3 f v1 v2 v3 = izipWith (\i a (b, c) -> f i a b c) v1 (zipWith (,) v2 v3)
zipWithM :: (Arity n, Applicative f) => (a -> b -> f c)
-> ContVec n a -> ContVec n b -> f (ContVec n c)
zipWithM f v w = sequence $ zipWith f v w
zipWithM_ :: (Arity n, Applicative f)
=> (a -> b -> f c) -> ContVec n a -> ContVec n b -> f ()
zipWithM_ f xs ys = sequence_ (zipWith f xs ys)
izipWithM :: (Arity n, Applicative f) => (Int -> a -> b -> f c)
-> ContVec n a -> ContVec n b -> f (ContVec n c)
izipWithM f v w = sequence $ izipWith f v w
izipWithM_ :: (Arity n, Applicative f)
=> (Int -> a -> b -> f c) -> ContVec n a -> ContVec n b -> f ()
izipWithM_ f xs ys = sequence_ (izipWith f xs ys)
izipWithF :: (ArityPeano n)
=> (Int -> a -> b -> c) -> Fun n c r -> Fun n a (Fun n b r)
izipWithF f (Fun g0) =
fmap (\v -> accum
(\(T_izip i (a:as) g) b -> T_izip (i+1) as (g $ f i a b))
(\(T_izip _ _ x) -> x)
(T_izip 0 v g0)
) makeList
makeList :: ArityPeano n => Fun n a [a]
makeList = accum
(\(Const xs) x -> Const (xs . (x:)))
(\(Const xs) -> xs [])
(Const id)
data T_izip a c r n = T_izip Int [a] (Fn n c r)
runContVec :: Fun (Peano n) a r
-> ContVec n a
-> r
runContVec f (ContVec c) = c f
vector :: (Vector v a, Dim v ~ n) => ContVec n a -> v a
vector = runContVec construct
head :: (Arity n, 1<=n) => ContVec n a -> a
head
= runContVec
$ accum (\(Const m) a -> Const $ case m of { Nothing -> Just a; x -> x })
(\(Const (Just x)) -> x)
(Const Nothing)
index :: Arity n => Int -> ContVec n a -> a
index n
| n < 0 = error "Data.Vector.Fixed.Cont.index: index out of range"
| otherwise = runContVec $ accum
(\(Const x) a -> Const $ case x of
Left 0 -> Right a
Left i -> Left (i 1)
r -> r
)
(\(Const x) -> case x of
Left _ -> error "Data.Vector.Fixed.index: index out of range"
Right a -> a
)
(Const (Left n))
element :: (Arity n, Functor f)
=> Int -> (a -> f a) -> ContVec n a -> f (ContVec n a)
element i f v = inspect v
$ elementF i f construct
elementF :: forall a n f r. (ArityPeano n, Functor f)
=> Int -> (a -> f a) -> Fun n a r -> Fun n a (f r)
elementF n f (Fun fun0) = accum step fini start
where
step :: forall k. T_lens f a r ('S k) -> a -> T_lens f a r k
step (T_lens (Left (0,fun))) a = T_lens $ Right $ fmap fun $ f a
step (T_lens (Left (i,fun))) a = T_lens $ Left (i1, fun a)
step (T_lens (Right fun)) a = T_lens $ Right $ fmap ($ a) fun
fini :: T_lens f a r 'Z -> f r
fini (T_lens (Left _)) = error "Data.Vector.Fixed.lensF: Index out of range"
fini (T_lens (Right r)) = r
start :: T_lens f a r n
start = T_lens $ Left (n,fun0)
data T_lens f a r n = T_lens (Either (Int,(Fn n a r)) (f (Fn n a r)))
foldl :: Arity n => (b -> a -> b) -> b -> ContVec n a -> b
foldl f = ifoldl (\b _ a -> f b a)
ifoldl :: Arity n => (b -> Int -> a -> b) -> b -> ContVec n a -> b
ifoldl f b v
= inspect v
$ accum (\(T_ifoldl i r) a -> T_ifoldl (i+1) (f r i a))
(\(T_ifoldl _ r) -> r)
(T_ifoldl 0 b)
foldM :: (Arity n, Monad m)
=> (b -> a -> m b) -> b -> ContVec n a -> m b
foldM f x
= foldl (\m a -> do{ b <- m; f b a}) (return x)
ifoldM :: (Arity n, Monad m)
=> (b -> Int -> a -> m b) -> b -> ContVec n a -> m b
ifoldM f x
= ifoldl (\m i a -> do{ b <- m; f b i a}) (return x)
data T_ifoldl b n = T_ifoldl !Int b
foldl1 :: (Arity n, 1 <= n) => (a -> a -> a) -> ContVec n a -> a
foldl1 f
= runContVec
$ accum (\(Const r ) a -> Const $ Just $ maybe a (flip f a) r)
(\(Const (Just x)) -> x)
(Const Nothing)
foldr :: Arity n => (a -> b -> b) -> b -> ContVec n a -> b
foldr = ifoldr . const
ifoldr :: Arity n => (Int -> a -> b -> b) -> b -> ContVec n a -> b
ifoldr f z
= runContVec
$ accum (\(T_ifoldr i g) a -> T_ifoldr (i+1) (g . f i a))
(\(T_ifoldr _ g) -> g z)
(T_ifoldr 0 id)
data T_ifoldr b n = T_ifoldr Int (b -> b)
sum :: (Num a, Arity n) => ContVec n a -> a
sum = foldl (+) 0
minimum :: (Ord a, Arity n, 1<=n) => ContVec n a -> a
minimum = foldl1 min
maximum :: (Ord a, Arity n, 1<=n) => ContVec n a -> a
maximum = foldl1 max
and :: Arity n => ContVec n Bool -> Bool
and = foldr (&&) True
or :: Arity n => ContVec n Bool -> Bool
or = foldr (||) False
all :: Arity n => (a -> Bool) -> ContVec n a -> Bool
all f = foldr (\x b -> f x && b) True
any :: Arity n => (a -> Bool) -> ContVec n a -> Bool
any f = foldr (\x b -> f x || b) True
find :: Arity n => (a -> Bool) -> ContVec n a -> Maybe a
find f = foldl (\r x -> r <|> if f x then Just x else Nothing) Nothing
gfoldl :: forall c v a. (Vector v a, Data a)
=> (forall x y. Data x => c (x -> y) -> x -> c y)
-> (forall x . x -> c x)
-> v a -> c (v a)
gfoldl f inj v
= inspect v
$ gfoldlF f (inj $ unFun (construct :: Fun (Peano (Dim v)) a (v a)))
gunfold :: forall con c v a. (Vector v a, Data a)
=> (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r)
-> con -> c (v a)
gunfold f inj _
= gunfoldF f gun
where
con = construct :: Fun (Peano (Dim v)) a (v a)
gun = T_gunfold (inj $ unFun con) :: T_gunfold c (v a) a (Peano (Dim v))
gfoldlF :: (ArityPeano n, Data a)
=> (forall x y. Data x => c (x -> y) -> x -> c y)
-> c (Fn n a r) -> Fun n a (c r)
gfoldlF f c0 = accum
(\(T_gfoldl c) x -> T_gfoldl (f c x))
(\(T_gfoldl c) -> c)
(T_gfoldl c0)
newtype T_gfoldl c r a n = T_gfoldl (c (Fn n a r))
newtype Const a n = Const a
type instance Dim Complex = 2
instance Vector Complex a where
construct = Fun (:+)
inspect (x :+ y) (Fun f) = f x y
type instance Dim Identity = 1
instance Vector Identity a where
construct = Fun Identity
inspect (Identity x) (Fun f) = f x
type instance Dim ((,) a) = 2
instance (b~a) => Vector ((,) b) a where
construct = Fun (,)
inspect (a,b) (Fun f) = f a b
type instance Dim ((,,) a b) = 3
instance (b~a, c~a) => Vector ((,,) b c) a where
construct = Fun (,,)
inspect (a,b,c) (Fun f) = f a b c
type instance Dim ((,,,) a b c) = 4
instance (b~a, c~a, d~a) => Vector ((,,,) b c d) a where
construct = Fun (,,,)
inspect (a,b,c,d) (Fun f) = f a b c d
type instance Dim ((,,,,) a b c d) = 5
instance (b~a, c~a, d~a, e~a) => Vector ((,,,,) b c d e) a where
construct = Fun (,,,,)
inspect (a,b,c,d,e) (Fun f) = f a b c d e
type instance Dim ((,,,,,) a b c d e) = 6
instance (b~a, c~a, d~a, e~a, f~a) => Vector ((,,,,,) b c d e f) a where
construct = Fun (,,,,,)
inspect (a,b,c,d,e,f) (Fun fun) = fun a b c d e f
type instance Dim ((,,,,,,) a b c d e f) = 7
instance (b~a, c~a, d~a, e~a, f~a, g~a) => Vector ((,,,,,,) b c d e f g) a where
construct = Fun (,,,,,,)
inspect (a,b,c,d,e,f,g) (Fun fun) = fun a b c d e f g
type instance Dim Proxy = 0
instance Vector Proxy a where
construct = Fun Proxy
inspect _ = unFun