{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{- |
Define some instance for NumericPrelude.Numeric type classes
in terms of Applicative and Foldable.
This is more elegant, but maybe not faster.
-}
module Sound.Frame.NumericPrelude.StereoApplicative (T, left, right, cons, map, ) where

import Sound.Frame.Stereo (T, left, right, cons, map, )

import qualified Algebra.NormedSpace.Maximum   as NormedMax
import qualified Algebra.NormedSpace.Euclidean as NormedEuc
import qualified Algebra.NormedSpace.Sum       as NormedSum

import qualified Algebra.Module    as Module
import qualified Algebra.Algebraic as Algebraic
import qualified Algebra.Additive  as Additive

import Control.Applicative (Applicative(pure), liftA2, )

import NumericPrelude.Numeric
import NumericPrelude.Base hiding (map)
import Prelude ()


instance (Additive.C a) => Additive.C (T a) where
   {-# INLINE zero #-}
   {-# INLINE negate #-}
   {-# INLINE (+) #-}
   {-# INLINE (-) #-}
   zero :: T a
zero   = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. C a => a
zero
   + :: T a -> T a -> T a
(+)    = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. C a => a -> a -> a
(+)
   (-)    = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (-)
   negate :: T a -> T a
negate = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. C a => a -> a
negate

instance (Module.C a v) => Module.C a (T v) where
   {-# INLINE (*>) #-}
   a
a*> :: a -> T v -> T v
*>T v
v = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
aforall a v. C a v => a -> v -> v
*>) T v
v


instance (Additive.C a, NormedSum.C a v) => NormedSum.C a (T v) where
   {-# INLINE norm #-}
   norm :: T v -> a
norm = forall a v (f :: * -> *).
(C a v, Foldable f, Functor f) =>
f v -> a
NormedSum.normFoldable1

instance (NormedEuc.Sqr a v) => NormedEuc.Sqr a (T v) where
   {-# INLINE normSqr #-}
   normSqr :: T v -> a
normSqr = forall a v (f :: * -> *).
(Sqr a v, Foldable f, Functor f) =>
f v -> a
NormedEuc.normSqrFoldable1

instance (Algebraic.C a, NormedEuc.Sqr a v) => NormedEuc.C a (T v) where
   {-# INLINE norm #-}
   norm :: T v -> a
norm = forall a v. (C a, Sqr a v) => v -> a
NormedEuc.defltNorm

instance (Ord a, NormedMax.C a v) => NormedMax.C a (T v) where
   {-# INLINE norm #-}
   norm :: T v -> a
norm = forall a v (f :: * -> *).
(C a v, Foldable f, Functor f) =>
f v -> a
NormedMax.normFoldable1