{-# Language TemplateHaskell #-}
module Language.Drasil.Uncertainty (
Uncertainty,
HasUncertainty(..),
uncert, prec,
uncty, exact,
defaultUncrt,
uncVal, uncPrec,
) where
import Control.Lens (Lens', (^.), makeLenses)
import Data.Maybe (fromMaybe)
data Uncertainty = Uncert {
Uncertainty -> Maybe Double
_uncert :: Maybe Double,
Uncertainty -> Maybe Int
_prec :: Maybe Int
}
makeLenses ''Uncertainty
class HasUncertainty c where
unc :: Lens' c Uncertainty
uncty :: Double -> Maybe Int -> Uncertainty
uncty :: Double -> Maybe Int -> Uncertainty
uncty Double
u = Maybe Double -> Maybe Int -> Uncertainty
Uncert (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. (Num a, Ord a) => a -> a
isDecimal Double
u)
exact :: Uncertainty
exact :: Uncertainty
exact = Maybe Double -> Maybe Int -> Uncertainty
Uncert forall a. Maybe a
Nothing forall a. Maybe a
Nothing
isDecimal :: (Num a, Ord a) => a -> a
isDecimal :: forall a. (Num a, Ord a) => a -> a
isDecimal a
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"An uncertain quantity cannot be exact (have 0% uncertainty). Reconsider whether your value is exact or uncertain"
isDecimal a
u = if (a
0 forall a. Ord a => a -> a -> Bool
< a
u) Bool -> Bool -> Bool
&& (a
u forall a. Ord a => a -> a -> Bool
< a
1) then a
u
else forall a. HasCallStack => [Char] -> a
error [Char]
"Uncertainty must be between 0 and 1"
defaultUncrt :: Uncertainty
defaultUncrt :: Uncertainty
defaultUncrt = Double -> Maybe Int -> Uncertainty
uncty Double
0.1 (forall a. a -> Maybe a
Just Int
0)
uncVal :: HasUncertainty x => x -> Double
uncVal :: forall x. HasUncertainty x => x -> Double
uncVal x
u = forall a. a -> Maybe a -> a
fromMaybe Double
0.0 forall a b. (a -> b) -> a -> b
$ x
u forall s a. s -> Getting a s a -> a
^. (forall c. HasUncertainty c => Lens' c Uncertainty
unc forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lens' Uncertainty (Maybe Double)
uncert)
uncPrec :: HasUncertainty x => x -> Maybe Int
uncPrec :: forall x. HasUncertainty x => x -> Maybe Int
uncPrec x
u = x
u forall s a. s -> Getting a s a -> a
^. (forall c. HasUncertainty c => Lens' c Uncertainty
unc forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lens' Uncertainty (Maybe Int)
prec)