module FishFood.Data.CommandOptions(
BinSizeDelta,
CommandOptions(
getBinSizeDelta,
getDeriveProbabilityMassFunction,
getNDecimalDigits,
getVerbosity
),
mkCommandOptions,
setBinSizeIncrement,
setBinSizeRatio
) where
import qualified Data.Default
import qualified Data.Maybe
import qualified Distribution.Verbosity
import qualified FishFood.Data.File as Data.File
import qualified ToolShed.SelfValidate
type BinSizeDelta ratio = Either (Maybe Data.File.FileSize) ratio
data CommandOptions ratio = MkCommandOptions {
getBinSizeDelta :: BinSizeDelta ratio,
getDeriveProbabilityMassFunction :: Bool,
getNDecimalDigits :: Int,
getVerbosity :: Distribution.Verbosity.Verbosity
} deriving Show
instance Data.Default.Default (CommandOptions ratio) where
def = MkCommandOptions {
getBinSizeDelta = Left Nothing,
getDeriveProbabilityMassFunction = False,
getNDecimalDigits = 3,
getVerbosity = Distribution.Verbosity.normal
}
instance (Num ratio, Ord ratio, Show ratio) => ToolShed.SelfValidate.SelfValidator (CommandOptions ratio) where
getErrors commandOptions@MkCommandOptions {
getBinSizeDelta = binSizeDelta,
getDeriveProbabilityMassFunction = deriveProbabilityMassFunction,
getNDecimalDigits = nDecimalDigits
} = map snd $ filter fst [
(
either (Data.Maybe.maybe False (<= 0)) (<= 1) binSizeDelta,
"either the bin-size's arithmetic increase must exceed zero, or it's geometric ratio must exceed one; " ++ show commandOptions ++ "."
), (
deriveProbabilityMassFunction && nDecimalDigits < 1,
"the number of decimal digits must exceed zero to adequately represent probabilities; " ++ show commandOptions ++ "."
),
let
maxNDecimalDigits = floor $ fromIntegral (
floatDigits (
undefined :: Double
)
) * (logBase 10 2 :: Double)
in (
nDecimalDigits > maxNDecimalDigits,
"the number of decimal digits shouldn't exceed " ++ show maxNDecimalDigits ++ "; " ++ show commandOptions ++ "."
)
]
mkCommandOptions :: (Num ratio, Ord ratio, Show ratio) => BinSizeDelta ratio -> Bool -> Int -> Distribution.Verbosity.Verbosity -> CommandOptions ratio
mkCommandOptions binSizeDelta deriveProbabilityMassFunction nDecimalDigits verbosity
| ToolShed.SelfValidate.isValid commandOptions = commandOptions
| otherwise = error $ "FishFood.Data.CommandOptions.mkCommandOptions:\t" ++ ToolShed.SelfValidate.getFirstError commandOptions
where
commandOptions = MkCommandOptions binSizeDelta deriveProbabilityMassFunction nDecimalDigits verbosity
setBinSizeIncrement :: Data.File.FileSize -> CommandOptions ratio -> CommandOptions ratio
setBinSizeIncrement fileSize commandOptions = commandOptions { getBinSizeDelta = Left $ Just fileSize }
setBinSizeRatio :: ratio -> CommandOptions ratio -> CommandOptions ratio
setBinSizeRatio ratio commandOptions = commandOptions { getBinSizeDelta = Right ratio }