{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Sound.Frame.NumericPrelude.Stereo (
   T, left, right, cons, map, swap,
   Stereo.Channel(Stereo.Left, Stereo.Right), Stereo.select,
   Stereo.interleave,
   Stereo.sequence,
   Stereo.liftApplicative,
   ) where

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

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 Algebra.Module   ((<*>.*>), )
import Algebra.Additive ((<*>.+), (<*>.-), (<*>.-$), )

import qualified NumericPrelude.Elementwise as Elem
import Control.Applicative (Applicative(pure), )

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 a. a -> a -> T a
cons forall a. C a => a
zero forall a. C a => a
zero
   + :: T a -> T a -> T a
(+)    = forall x y a. T (x, y) a -> x -> y -> a
Elem.run2 forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. a -> a -> T a
cons forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.+  forall a. T a -> a
left forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.+  forall a. T a -> a
right
   (-)    = forall x y a. T (x, y) a -> x -> y -> a
Elem.run2 forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. a -> a -> T a
cons forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.-  forall a. T a -> a
left forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.-  forall a. T a -> a
right
   negate :: T a -> T a
negate = forall v a. T v a -> v -> a
Elem.run  forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. a -> a -> T a
cons forall x v a. C x => T v (x -> a) -> (v -> x) -> T v a
<*>.-$ forall a. T a -> a
left forall x v a. C x => T v (x -> a) -> (v -> x) -> T v a
<*>.-$ forall a. T a -> a
right

instance (Module.C a v) => Module.C a (T v) where
   {-# INLINE (*>) #-}
   *> :: a -> T v -> T v
(*>) = forall x y a. T (x, y) a -> x -> y -> a
Elem.run2 forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. a -> a -> T a
cons forall a x v c.
C a x =>
T (a, v) (x -> c) -> (v -> x) -> T (a, v) c
<*>.*> forall a. T a -> a
left forall a x v c.
C a x =>
T (a, v) (x -> c) -> (v -> x) -> T (a, v) c
<*>.*> forall a. T a -> a
right


instance (Additive.C a, NormedSum.C a v) => NormedSum.C a (T v) where
   {-# INLINE norm #-}
   norm :: T v -> a
norm T v
x =
      forall a v. C a v => v -> a
NormedSum.norm (forall a. T a -> a
left T v
x) forall a. C a => a -> a -> a
+ forall a v. C a v => v -> a
NormedSum.norm (forall a. T a -> a
right T v
x)

instance (NormedEuc.Sqr a v) => NormedEuc.Sqr a (T v) where
   {-# INLINE normSqr #-}
   normSqr :: T v -> a
normSqr T v
x =
      forall a v. Sqr a v => v -> a
NormedEuc.normSqr (forall a. T a -> a
left T v
x) forall a. C a => a -> a -> a
+ forall a v. Sqr a v => v -> a
NormedEuc.normSqr (forall a. T a -> a
right T v
x)

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 T v
x =
      forall a. Ord a => a -> a -> a
max (forall a v. C a v => v -> a
NormedMax.norm (forall a. T a -> a
left T v
x)) (forall a v. C a v => v -> a
NormedMax.norm (forall a. T a -> a
right T v
x))