ad-0.28: Numeric/AD/Internal/Tensors.hs
{-# LANGUAGE TypeOperators, TemplateHaskell, ScopedTypeVariables #-}
-- {-# OPTIONS_HADDOCK hide #-}
-----------------------------------------------------------------------------
-- |
-- Module : Numeric.AD.Internal.Tensors
-- Copyright : (c) Edward Kmett 2010
-- License : BSD3
-- Maintainer : ekmett@gmail.com
-- Stability : experimental
-- Portability : GHC only
--
-----------------------------------------------------------------------------
module Numeric.AD.Internal.Tensors
( Tensors(..)
, headT
, tailT
, tensors
) where
import Control.Applicative
import Data.Foldable
import Data.Traversable
import Data.Monoid
--import Data.Data
--import Data.Typeable
import Numeric.AD.Internal.Comonad
import Numeric.AD.Internal.Stream
infixl 3 :-
data Tensors f a = a :- Tensors f (f a)
-- TODO: deriving (Data, Typeable)
instance Functor f => Functor (Tensors f) where
fmap f (a :- as) = f a :- fmap (fmap f) as
instance Foldable f => Foldable (Tensors f) where
foldMap f (a :- as) = f a `mappend` foldMap (foldMap f) as
instance Traversable f => Traversable (Tensors f) where
traverse f (a :- as) = (:-) <$> f a <*> traverse (traverse f) as
-- | While we can not be a 'Comonad' without a 'fzip'-like operation, you can use the
-- comonad for @'Stream' f a@ to manipulate a structure comonadically that you can turn
-- into 'Tensors'.
instance Functor f => Copointed (Tensors f) where
extract (a :- _) = a
tailT :: Tensors f a -> Tensors f (f a)
tailT (_ :- as) = as
{-# INLINE tailT #-}
headT :: Tensors f a -> a
headT (a :- _) = a
{-# INLINE headT #-}
tensors :: Functor f => Stream f a -> Tensors f a
tensors (a :< as) = a :- distribute (tensors <$> as)
where
distribute :: Functor f => f (Tensors f a) -> Tensors f (f a)
distribute x = (headT <$> x) :- distribute (tailT <$> x)