{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- -- | -- Copyright : (c) Edward Kmett 2010-2021 -- License : BSD3 -- Maintainer : ekmett@gmail.com -- Stability : experimental -- Portability : GHC only -- -- Combinators used internally by @Numeric.AD@ ----------------------------------------------------------------------------- module Numeric.AD.Internal.Combinators ( zipWithT , zipWithDefaultT , withPrimal , fromBy , takeWhileDifferent ) where import Data.Traversable (mapAccumL) import Data.Foldable (toList) import Numeric.AD.Mode import Numeric.AD.Jacobian -- | Zip a @'Foldable' f@ with a @'Traversable' g@ assuming @f@ has at least as many entries as @g@. zipWithT :: (Foldable f, Traversable g) => (a -> b -> c) -> f a -> g b -> g c zipWithT f as = snd . mapAccumL f' (toList as) where f' (a:as') b = (as', f a b) f' [] _ = error "zipWithT: second argument contains less entries than third argument" -- | Zip a @'Foldable' f@ with a @'Traversable' g@ assuming @f@, using a default value after @f@ is exhausted. zipWithDefaultT :: (Foldable f, Traversable g) => a -> (a -> b -> c) -> f a -> g b -> g c zipWithDefaultT z f as = zipWithT f (toList as ++ repeat z) -- | Used internally to define various 'Enum' combinators. withPrimal :: Jacobian t => t -> Scalar t -> t withPrimal t a = unary (const a) 1 t {-# INLINE withPrimal #-} -- | Used internally to define various 'Enum' combinators. fromBy :: Jacobian t => t -> t -> Int -> Scalar t -> t fromBy a delta n x = binary (\_ _ -> x) 1 (fromIntegral n) a delta -- | Used internally to implement functions which truncate lists after the -- stream of results converge takeWhileDifferent :: Eq a => [a] -> [a] takeWhileDifferent (x1:x2:xs) = if x1 == x2 then [x1] else x1 : takeWhileDifferent (x2:xs) takeWhileDifferent xs = xs