{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Numeric.Rounded.Hardware.Internal.RoundedResult where
import Data.Proxy
import Data.Functor.Product
import Numeric.Rounded.Hardware.Internal.Rounding
class Functor f => Result f where
exact :: a -> f a
inexact :: a
-> a
-> a
-> a
-> f a
newtype Exactness a = Exactness { getExactness :: Bool }
deriving (Eq, Ord, Show, Functor)
instance Rounding r => Result (Rounded r) where
exact x = Rounded x
inexact n inf ninf z = case rounding (Proxy :: Proxy r) of
ToNearest -> Rounded n
TowardInf -> Rounded inf
TowardNegInf -> Rounded ninf
TowardZero -> Rounded z
newtype DynamicRoundingMode a = DynamicRoundingMode { withRoundingMode :: RoundingMode -> a }
deriving (Functor)
instance Result DynamicRoundingMode where
exact x = DynamicRoundingMode (\_ -> x)
inexact n inf ninf z = DynamicRoundingMode $ \r ->
case r of
ToNearest -> n
TowardInf -> inf
TowardNegInf -> ninf
TowardZero -> z
instance Result Exactness where
exact _ = Exactness True
inexact _ _ _ _ = Exactness False
instance (Result f, Result g) => Result (Product f g) where
exact x = Pair (exact x) (exact x)
inexact n inf ninf z = Pair (inexact n inf ninf z) (inexact n inf ninf z)
newtype OppositeRoundingMode f a = OppositeRoundingMode { withOppositeRoundingMode :: f a }
deriving (Eq, Ord, Show, Functor)
instance Result f => Result (OppositeRoundingMode f) where
exact x = OppositeRoundingMode (exact x)
inexact n inf ninf z = OppositeRoundingMode (inexact n ninf inf z)