module Data.Vector.Fixed.Cont (
S
, Z
, N1
, N2
, N3
, N4
, N5
, N6
, Fn
, Fun(..)
, Arity(..)
, apply
, applyM
, apFun
, apLast
, constFun
, hideLast
, shuffleFun
, Dim
, Vector(..)
, VectorN
, length
, Index(..)
, ContVec(..)
, cvec
, fromList
, fromList'
, fromListM
, toList
, replicate
, replicateM
, generate
, generateM
, unfoldr
, basis
, empty
, cons
, consV
, snoc
, mk1
, mk2
, mk3
, mk4
, mk5
, map
, imap
, mapM
, imapM
, mapM_
, imapM_
, sequence
, sequence_
, tail
, reverse
, zipWith
, izipWith
, zipWithM
, izipWithM
, runContVec
, head
, index
, element
, elementTy
, vector
, foldl
, foldl1
, foldr
, ifoldl
, ifoldr
, foldM
, ifoldM
, sum
, minimum
, maximum
, and
, or
, all
, any
) where
import Control.Applicative (Applicative(..),(<$>))
import Data.Complex (Complex(..))
import Data.Typeable (Typeable(..))
import qualified Data.Foldable as F
import qualified Data.Traversable as F
import Prelude hiding ( replicate,map,zipWith,maximum,minimum,and,or,any,all
, foldl,foldr,foldl1,length,sum,reverse
, head,tail,mapM,mapM_,sequence,sequence_
)
data Z deriving Typeable
data S n deriving Typeable
type N1 = S Z
type N2 = S N1
type N3 = S N2
type N4 = S N3
type N5 = S N4
type N6 = S N5
type family Fn n a b
type instance Fn Z a b = b
type instance Fn (S n) a b = a -> Fn n a b
newtype Fun n a b = Fun { unFun :: Fn n a b }
instance Arity n => Functor (Fun n a) where
fmap (f :: b -> c) (Fun g0 :: Fun n a b)
= Fun $ accum
(\(T_fmap g) a -> T_fmap (g a))
(\(T_fmap x) -> f x)
(T_fmap g0 :: T_fmap a b n)
instance Arity n => Applicative (Fun n a) where
pure (x :: x) = Fun $ accum (\(T_pure r) (_::a) -> T_pure r)
(\(T_pure r) -> r)
(T_pure x :: T_pure x n)
(Fun f0 :: Fun n a (p -> q)) <*> (Fun g0 :: Fun n a p)
= Fun $ 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 Arity n => Monad (Fun n a) where
return = pure
f >>= g = shuffleFun g <*> f
newtype T_fmap a b n = T_fmap (Fn n a b)
data T_pure a n = T_pure a
data T_ap a b c n = T_ap (Fn n a b) (Fn n a c)
class Arity n where
accum :: (forall k. t (S k) -> a -> t k)
-> (t Z -> b)
-> t n
-> Fn n a b
applyFun :: (forall k. t (S k) -> (a, t k))
-> t n
-> Fn n a b
-> (b, t Z)
applyFunM :: Monad m
=> (forall k. t (S k) -> m (a, t k))
-> t n
-> m (ContVec n a, t Z)
arity :: n -> Int
reverseF :: Fun n a b -> Fun n a b
apply :: Arity n
=> (forall k. t (S k) -> (a, t k))
-> t n
-> Fn n a b
-> b
apply step z f = fst $ applyFun step z f
applyM :: (Monad m, Arity n)
=> (forall k. t (S k) -> m (a, t k))
-> t n
-> m (ContVec n a)
applyM f t = do (v,_) <- applyFunM f t
return v
instance Arity Z where
accum _ g t = g t
applyFun _ t h = (h,t)
applyFunM _ t = return (empty, t)
arity _ = 0
reverseF = id
instance Arity n => Arity (S n) where
accum f g t = \a -> accum f g (f t a)
applyFun f t h = case f t of (a,u) -> applyFun f u (h a)
applyFunM f t = do (a,t') <- f t
(ContVec cont, tZ) <- applyFunM f t'
return (ContVec $ \g -> cont (apFun g a) , tZ)
arity _ = 1 + arity (undefined :: n)
reverseF f = Fun $ \a -> unFun (reverseF $ fmap ($ a) $ hideLast f)
apFun :: Fun (S n) a b -> a -> Fun n a b
apFun (Fun f) x = Fun (f x)
apLast :: Arity n => Fun (S n) a b -> a -> Fun n a b
apLast f x = fmap ($ x) $ hideLast f
constFun :: Fun n a b -> Fun (S n) a b
constFun (Fun f) = Fun $ \_ -> f
hideLast :: forall n a b. Arity n => Fun (S n) a b -> Fun n a (a -> b)
hideLast (Fun f0) = Fun $ accum (\(T_fun f) a -> T_fun (f a))
(\(T_fun f) -> f)
(T_fun f0 :: T_fun a b n)
newtype T_fun a b n = T_fun (Fn (S n) a b)
shuffleFun :: forall n a b r. Arity n
=> (b -> Fun n a r) -> Fun n a (b -> r)
shuffleFun f0
= Fun $ accum (\(T_shuffle f) a -> T_shuffle $ \x -> f x a)
(\(T_shuffle f) -> f)
(T_shuffle (fmap unFun f0) :: T_shuffle b a r n)
newtype T_shuffle x a r n = T_shuffle (x -> Fn n a r)
type family Dim (v :: * -> *)
class Arity (Dim v) => Vector v a where
construct :: Fun (Dim v) a (v a)
inspect :: v a -> Fun (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. Arity (Dim v) => v a -> Int
length _ = arity (undefined :: Dim v)
class Index k n where
getF :: k -> Fun n a a
lensF :: Functor f => k -> (a -> f a) -> Fun n a r -> Fun n a (f r)
instance Arity n => Index Z (S n) where
getF _ = Fun $ \(a :: a) -> unFun (pure a :: Fun n a a)
lensF _ f fun = Fun $ \(a :: a) -> unFun $
(\g -> g <$> f a) <$> shuffleFun (apFun fun)
instance Index k n => Index (S k) (S n) where
getF _ = Fun $ \(_::a) -> unFun (getF (undefined :: k) :: Fun n a a)
lensF _ f fun = Fun $ \a -> unFun (lensF (undefined :: k) f (apFun fun a))
newtype ContVec n a = ContVec (forall r. Fun n a r -> r)
type instance Dim (ContVec n) = n
instance Arity n => Vector (ContVec n) a where
construct = Fun $
accum (\(T_mkN f) a -> T_mkN (f . cons a))
(\(T_mkN f) -> f empty)
(T_mkN id :: T_mkN n a n)
inspect (ContVec c) f = c f
newtype T_mkN n_tot a n = T_mkN (ContVec n a -> ContVec 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, Arity n)
=> Fun n a b -> Fun n (f a) (f b)
sequenceAF (Fun f0)
= Fun $ 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 Z a
empty = ContVec (\(Fun r) -> r)
fromList :: forall n a. Arity n => [a] -> ContVec n a
fromList xs = ContVec $ \(Fun fun) ->
apply step
(T_flist xs :: T_flist a n)
fun
where
step (T_flist [] ) = error "Data.Vector.Fixed.Cont.fromList: too few elements"
step (T_flist (a:as)) = (a, T_flist as)
fromList' :: forall n a. Arity n => [a] -> ContVec n a
fromList' xs = ContVec $ \(Fun fun) ->
let (r,rest) = applyFun step (T_flist xs :: T_flist a n) fun
step (T_flist [] ) = error "Data.Vector.Fixed.Cont.fromList': too few elements"
step (T_flist (a:as)) = (a, T_flist as)
in case rest of
T_flist [] -> r
_ -> error "Data.Vector.Fixed.Cont.fromList': too many elements"
fromListM :: forall n a. Arity n => [a] -> Maybe (ContVec n a)
fromListM xs = do
(v,rest) <- applyFunM step (T_flist xs :: T_flist a n)
case rest of
T_flist [] -> return v
_ -> Nothing
where
step (T_flist [] ) = Nothing
step (T_flist (a:as)) = return (a, T_flist as)
data T_flist a n = T_flist [a]
toList :: (Arity n) => ContVec n a -> [a]
toList = foldr (:) []
replicate :: forall n a. (Arity n)
=> a -> ContVec n a
replicate a = ContVec $ \(Fun fun) ->
apply (\T_replicate -> (a, T_replicate))
(T_replicate :: T_replicate n)
fun
replicateM :: forall m n a. (Arity n, Monad m)
=> m a -> m (ContVec n a)
replicateM act =
applyM (\T_replicate -> do { a <- act; return (a, T_replicate) } )
(T_replicate :: T_replicate n)
data T_replicate n = T_replicate
generate :: forall n a. (Arity n) => (Int -> a) -> ContVec n a
generate f = ContVec $ \(Fun fun) ->
apply (\(T_generate n) -> (f n, T_generate (n + 1)))
(T_generate 0 :: T_generate n)
fun
generateM :: forall m n a. (Monad m, Arity n)
=> (Int -> m a) -> m (ContVec n a)
generateM f =
applyM (\(T_generate n) -> do { a <- f n; return (a, T_generate (n + 1)) } )
(T_generate 0 :: T_generate n)
newtype T_generate n = T_generate Int
unfoldr :: forall n b a. Arity n => (b -> (a,b)) -> b -> ContVec n a
unfoldr f b0 = ContVec $ \(Fun fun) ->
apply (\(T_unfoldr b) -> let (a,b') = f b in (a, T_unfoldr b'))
(T_unfoldr b0 :: T_unfoldr b n)
fun
newtype T_unfoldr b n = T_unfoldr b
basis :: forall n a. (Num a, Arity n) => Int -> ContVec n a
basis n0 = ContVec $ \(Fun fun) ->
apply (\(T_basis n) -> ((if n == 0 then 1 else 0) :: a, T_basis (n 1)))
(T_basis n0 :: T_basis n)
fun
newtype T_basis n = T_basis Int
mk1 :: a -> ContVec N1 a
mk1 a1 = ContVec $ \(Fun f) -> f a1
mk2 :: a -> a -> ContVec N2 a
mk2 a1 a2 = ContVec $ \(Fun f) -> f a1 a2
mk3 :: a -> a -> a -> ContVec N3 a
mk3 a1 a2 a3 = ContVec $ \(Fun f) -> f a1 a2 a3
mk4 :: a -> a -> a -> a -> ContVec N4 a
mk4 a1 a2 a3 a4 = ContVec $ \(Fun f) -> f a1 a2 a3 a4
mk5 :: a -> a -> a -> a -> a -> ContVec N5 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, Monad m) => (a -> m b) -> ContVec n a -> m (ContVec n b)
mapM = imapM . const
imapM :: (Arity n, Monad m) => (Int -> a -> m b) -> ContVec n a -> m (ContVec n b)
imapM f v
= inspect v
$ imapMF f construct
mapM_ :: (Arity n, Monad m) => (a -> m b) -> ContVec n a -> m ()
mapM_ f = foldl (\m a -> m >> f a >> return ()) (return ())
imapM_ :: (Arity n, Monad m) => (Int -> a -> m b) -> ContVec n a -> m ()
imapM_ f = ifoldl (\m i a -> m >> f i a >> return ()) (return ())
imapMF :: forall m n a b r. (Arity n, Monad m)
=> (Int -> a -> m b) -> Fun n b r -> Fun n a (m r)
imapMF f (Fun funB) = Fun $
accum (\(T_mapM i m) a -> T_mapM (i+1) $ do b <- f i a
fun <- m
return $ fun b
)
(\(T_mapM _ m) -> m)
(T_mapM 0 (return funB) :: T_mapM b m r n)
data T_mapM a m r n = T_mapM Int (m (Fn n a r))
imapF :: forall n a b r. Arity n
=> (Int -> a -> b) -> Fun n b r -> Fun n a r
imapF f (Fun funB) = Fun $
accum (\(T_map i g) b -> T_map (i+1) (g (f i b)))
(\(T_map _ r) -> r)
( T_map 0 funB :: T_map b r n)
data T_map a r n = T_map Int (Fn n a r)
sequence :: (Arity n, Monad m) => ContVec n (m a) -> m (ContVec n a)
sequence = mapM id
sequence_ :: (Arity n, Monad m) => ContVec n (m a) -> m ()
sequence_ = mapM_ id
tail :: ContVec (S n) a -> ContVec n a
tail (ContVec cont) = ContVec $ \f -> cont $ constFun f
cons :: a -> ContVec n a -> ContVec (S n) a
cons a (ContVec cont) = ContVec $ \f -> cont $ apFun f a
consV :: forall n a. ContVec (S Z) a -> ContVec n a -> ContVec (S n) a
consV (ContVec cont1) (ContVec cont)
= ContVec $ \f -> cont $ apFun f $ cont1 $ Fun id
snoc :: Arity n => a -> ContVec n a -> ContVec (S n) a
snoc a (ContVec cont) = ContVec $ \f -> cont $ apLast f a
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
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
zipWithM :: (Arity n, Monad m) => (a -> b -> m c)
-> ContVec n a -> ContVec n b -> m (ContVec n c)
zipWithM f v w = sequence $ zipWith f v w
izipWithM :: (Arity n, Monad m) => (Int -> a -> b -> m c)
-> ContVec n a -> ContVec n b -> m (ContVec n c)
izipWithM f v w = sequence $ izipWith f v w
izipWithF :: forall n a b c r. (Arity n)
=> (Int -> a -> b -> c) -> Fun n c r -> Fun n a (Fun n b r)
izipWithF f (Fun g0) =
fmap (\v -> Fun $ 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 :: (T_izip a c r n))
) makeList
makeList :: forall n a. Arity n => Fun n a [a]
makeList = Fun $ accum
(\(T_mkList xs) x -> T_mkList (xs . (x:)))
(\(T_mkList xs) -> xs [])
(T_mkList id :: T_mkList a n)
newtype T_mkList a n = T_mkList ([a] -> [a])
data T_izip a c r n = T_izip Int [a] (Fn n c r)
runContVec :: Arity n
=> Fun 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 :: forall n a. Arity (S n) => ContVec (S n) a -> a
head
= runContVec $ Fun
$ accum (\(T_head m) a -> T_head $ case m of { Nothing -> Just a; x -> x })
(\(T_head (Just x)) -> x)
(T_head Nothing :: T_head a (S n))
data T_head a n = T_head (Maybe a)
index :: forall n a. Arity n => Int -> ContVec n a -> a
index n
| n < 0 = error "Data.Vector.Fixed.Cont.index: index out of range"
| otherwise = runContVec $ Fun $ accum
(\(T_Index x) a -> T_Index $ case x of
Left 0 -> Right a
Left i -> Left (i 1)
r -> r
)
(\(T_Index x) -> case x of
Left _ -> error "Data.Vector.Fixed.index: index out of range"
Right a -> a
)
( T_Index (Left n) :: T_Index a n)
newtype T_Index a n = T_Index (Either Int a)
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
elementTy :: (Arity n, Index k n, Functor f)
=> k -> (a -> f a) -> ContVec n a -> f (ContVec n a)
elementTy k f v = inspect v
$ lensF k f construct
elementF :: forall a n f r. (Arity n, Functor f)
=> Int -> (a -> f a) -> Fun n a r -> Fun n a (f r)
elementF n f (Fun fun0) = Fun $ 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 :: forall n a b. Arity n
=> (b -> Int -> a -> b) -> b -> ContVec n a -> b
ifoldl f b v
= inspect v $ Fun
$ accum (\(T_ifoldl i r) a -> T_ifoldl (i+1) (f r i a))
(\(T_ifoldl _ r) -> r)
(T_ifoldl 0 b :: T_ifoldl b n)
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
newtype T_foldl1 a n = T_foldl1 (Maybe a)
foldl1 :: forall n a. (Arity (S n))
=> (a -> a -> a) -> ContVec (S n) a -> a
foldl1 f
= runContVec $ Fun
$ accum (\(T_foldl1 r ) a -> T_foldl1 $ Just $ maybe a (flip f a) r)
(\(T_foldl1 (Just x)) -> x)
(T_foldl1 Nothing :: T_foldl1 a (S n))
foldr :: Arity n => (a -> b -> b) -> b -> ContVec n a -> b
foldr = ifoldr . const
ifoldr :: forall n a b. Arity n
=> (Int -> a -> b -> b) -> b -> ContVec n a -> b
ifoldr f z
= runContVec $ Fun
$ accum (\(T_ifoldr i g) a -> T_ifoldr (i+1) (g . f i a))
(\(T_ifoldr _ g) -> g z)
(T_ifoldr 0 id :: T_ifoldr b n)
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 (S n)) => ContVec (S n) a -> a
minimum = foldl1 min
maximum :: (Ord a, Arity (S n)) => ContVec (S 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
type instance Dim Complex = N2
instance RealFloat a => Vector Complex a where
construct = Fun (:+)
inspect (x :+ y) (Fun f) = f x y
type instance Dim ((,) a) = N2
instance (b~a) => Vector ((,) b) a where
construct = Fun (,)
inspect (a,b) (Fun f) = f a b
type instance Dim ((,,) a b) = N3
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) = N4
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) = N5
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) = N6
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) = S N6
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