{-# LANGUAGE TypeOperators, TemplateHaskell, ScopedTypeVariables, FlexibleContexts #-} {-# 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 #if __GLASGOW_HASKELL__ < 704 import Data.Typeable (Typeable1(..), TyCon, mkTyCon, mkTyConApp) #else import Data.Typeable (Typeable1(..), TyCon, mkTyCon3, mkTyConApp) #endif import Control.Comonad.Cofree infixl 3 :- data Tensors f a = a :- Tensors f (f a) newtype Showable = Showable (Int -> String -> String) instance Show Showable where showsPrec d (Showable f) = f d showable :: Show a => a -> Showable showable a = Showable (\d -> showsPrec d a) -- Polymorphic recursion precludes 'Data' in its current form, as no Data1 class exists -- Polymorphic recursion also breaks 'show' for 'Tensors'! -- factor Show1 out of Lifted? instance (Functor f, Show (f Showable), Show a) => Show (Tensors f a) where showsPrec d (a :- as) = showParen (d > 3) $ showsPrec 4 a . showString " :- " . showsPrec 3 (fmap showable <$> as) 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 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 => Cofree f a -> Tensors f a tensors (a :< as) = a :- dist (tensors <$> as) where dist :: Functor f => f (Tensors f a) -> Tensors f (f a) dist x = (headT <$> x) :- dist (tailT <$> x) instance Typeable1 f => Typeable1 (Tensors f) where typeOf1 tfa = mkTyConApp tensorsTyCon [typeOf1 (undefined `asArgsType` tfa)] where asArgsType :: f a -> t f a -> f a asArgsType = const tensorsTyCon :: TyCon #if __GLASGOW_HASKELL__ < 704 tensorsTyCon = mkTyCon "Numeric.AD.Internal.Tensors.Tensors" #else tensorsTyCon = mkTyCon3 "ad" "Numeric.AD.Internal.Tensors" "Tensors" #endif {-# NOINLINE tensorsTyCon #-}