{-# OPTIONS_GHC -Wall #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | multi-dimensional representable numbers module NumHask.Naperian ( Naperian , HasShape(..) , module Data.Functor.Rep ) where import Protolude (Int, foldr, Foldable(..), ($), (<$>), fmap, fst, snd, or, and) import Data.Functor.Rep import NumHask.Prelude -- | ToDo: integrate with Naperian instance class HasShape f where type Shape f shape :: f a -> Shape f ndim :: f a -> Int class (HasShape f, Representable f) => Naperian f instance {-# Overlappable #-} (Naperian f, AdditiveMagma a) => AdditiveMagma (f a) where plus = liftR2 plus instance {-# Overlappable #-} (Naperian f, AdditiveUnital a) => AdditiveUnital (f a) where zero = pureRep zero instance {-# Overlappable #-} (Naperian f, AdditiveAssociative a) => AdditiveAssociative (f a) instance {-# Overlappable #-} (Naperian f, AdditiveCommutative a) => AdditiveCommutative (f a) instance {-# Overlappable #-} (Naperian f, AdditiveInvertible a) => AdditiveInvertible (f a) where negate = fmapRep negate instance {-# Overlappable #-} (Naperian f, AdditiveMagma a) => AdditiveHomomorphic a (f a) where plushom a = pureRep a instance {-# Overlappable #-} (Naperian f, AdditiveMonoidal a) => AdditiveMonoidal (f a) instance {-# Overlappable #-} (Naperian f, Additive a) => Additive (f a) instance {-# Overlappable #-} (Naperian f, AdditiveGroup a) => AdditiveGroup (f a) instance {-# Overlappable #-} (Naperian f, MultiplicativeMagma a) => MultiplicativeMagma (f a) where times = liftR2 times instance {-# Overlappable #-} (Naperian f, MultiplicativeUnital a) => MultiplicativeUnital (f a) where one = pureRep one instance {-# Overlappable #-} (Naperian f, MultiplicativeAssociative a) => MultiplicativeAssociative (f a) instance {-# Overlappable #-} (Naperian f, MultiplicativeCommutative a) => MultiplicativeCommutative (f a) instance {-# Overlappable #-} (Naperian f, MultiplicativeInvertible a) => MultiplicativeInvertible (f a) where recip = fmapRep recip instance {-# Overlappable #-} (Naperian f, MultiplicativeMagma a) => MultiplicativeHomomorphic a (f a) where timeshom a = pureRep a instance {-# Overlappable #-} (Naperian f, MultiplicativeMonoidal a) => MultiplicativeMonoidal (f a) instance {-# Overlappable #-} (Naperian f, Multiplicative a) => Multiplicative (f a) instance {-# Overlappable #-} (Naperian f, MultiplicativeGroup a) => MultiplicativeGroup (f a) instance {-# Overlappable #-} (Naperian f, MultiplicativeMagma a, Additive a) => Distribution (f a) instance {-# Overlappable #-} (Naperian f, Semiring a) => Semiring (f a) instance {-# Overlappable #-} (Naperian f, Ring a) => Ring (f a) instance {-# Overlappable #-} (Naperian f, CRing a) => CRing (f a) instance {-# Overlappable #-} (Naperian f, Field a) => Field (f a) instance {-# Overlappable #-} (Naperian f, ExpField a) => ExpField (f a) where exp = fmapRep exp log = fmapRep log instance {-# Overlappable #-} (Naperian f, BoundedField a, Foldable f) => BoundedField (f a) where isNaN f = or (fmapRep isNaN f) instance {-# Overlappable #-} (Naperian f, Signed a) => Signed (f a) where sign = fmapRep sign abs = fmapRep abs instance {-# Overlappable #-} (Foldable f, Naperian f, ExpField a) => Normed (f a) a where size r = sqrt $ foldr (+) zero $ (**(one+one)) <$> r instance {-# Overlappable #-} (Foldable f, Naperian f, Epsilon a) => Epsilon (f a) where nearZero f = and (fmapRep nearZero f) aboutEqual a b = and (liftR2 aboutEqual a b) instance {-# Overlappable #-} (Foldable f, Naperian f, ExpField a) => Metric (f a) a where distance a b = size (a - b) instance {-# Overlappable #-} (Naperian f, Integral a) => Integral (f a) where divMod a b = (d,m) where x = liftR2 divMod a b d = fmap fst x m = fmap snd x