module Numeric.Netlib.Class where

import Foreign.Storable.Complex ()
import Foreign.Storable (Storable)

import Data.Functor.Compose (Compose(Compose, getCompose))
import Data.Complex (Complex)

import qualified Prelude
import Prelude (Float, Double, ($))


class (Floating a, Prelude.RealFloat a) => Real a where
   switchReal :: f Float -> f Double -> f a

instance Real Float where switchReal :: forall (f :: * -> *). f Float -> f Double -> f Float
switchReal f Float
f f Double
_ = f Float
f
instance Real Double where switchReal :: forall (f :: * -> *). f Float -> f Double -> f Double
switchReal f Float
_ f Double
f = f Double
f


class (Storable a, Prelude.Fractional a) => Floating a where
   switchFloating ::
      f Float -> f Double ->
      f (Complex Float) -> f (Complex Double) -> f a

instance Floating Float where switchFloating :: forall (f :: * -> *).
f Float
-> f Double -> f (Complex Float) -> f (Complex Double) -> f Float
switchFloating f Float
f f Double
_ f (Complex Float)
_ f (Complex Double)
_ = f Float
f
instance Floating Double where switchFloating :: forall (f :: * -> *).
f Float
-> f Double -> f (Complex Float) -> f (Complex Double) -> f Double
switchFloating f Float
_ f Double
f f (Complex Float)
_ f (Complex Double)
_ = f Double
f
instance (Real a) => Floating (Complex a) where
   switchFloating :: forall (f :: * -> *).
f Float
-> f Double
-> f (Complex Float)
-> f (Complex Double)
-> f (Complex a)
switchFloating f Float
_ f Double
_ f (Complex Float)
fz f (Complex Double)
fc = Compose f Complex a -> f (Complex a)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose f Complex a -> f (Complex a))
-> Compose f Complex a -> f (Complex a)
forall a b. (a -> b) -> a -> b
$ Compose f Complex Float
-> Compose f Complex Double -> Compose f Complex a
forall a (f :: * -> *). Real a => f Float -> f Double -> f a
forall (f :: * -> *). f Float -> f Double -> f a
switchReal (f (Complex Float) -> Compose f Complex Float
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (Complex Float)
fz) (f (Complex Double) -> Compose f Complex Double
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (Complex Double)
fc)