calculator-0.3.0.0: src/Calculator/Prim/Function.hs
module Calculator.Prim.Function
( Function (..)
, mkFunc
, mkFuncEither
, oneArg
, partial
, testFunc
) where
--------------------------------------------------------------------------------
-- | Represents a function, where rank == No. of arguments
data Function = Function {
arity :: Int
, apply :: [Double] -> Either [String] Double
}
--------------------------------------------------------------------------------
-- | Make a @Function@ out of an arity and another function
mkFunc :: Int -> ([Double] -> Double) -> Function
mkFunc a f = mkFuncEither a (Right . f)
--------------------------------------------------------------------------------
-- | Make a @Function@ with an arity using an error giving function
mkFuncEither :: Int -> ([Double] -> Either [String] Double) -> Function
mkFuncEither a f = Function { arity = a , apply = g }
where g xs = if length xs == a
then f xs
else Left [ "Invalid no. of arguments"
, "Required: " ++ show a
, "Provided: " ++ show (length xs)
]
--------------------------------------------------------------------------------
-- | Make a @Function@ out of a single argument function
oneArg :: (Double -> Double) -> Function
oneArg f = mkFunc 1 (\ [x] -> f x)
--------------------------------------------------------------------------------
-- | Partially apply a function, thus creating a one-argument function.
-- To be used for parametrized functions, e.g getting g(x) = f(x,1,2)
-- this retains the free-variable 'x'
partial :: Function -> [Double] -> Double -> Maybe Double
partial f xs x = case apply f (x:xs) of
Left _ -> Nothing
Right v -> Just v
--------------------------------------------------------------------------------
-- | Test a @Function@ with some value t, useful for sanity checking
-- while adding a @Function@ to a @Bindings@
testFunc :: Function -> Double -> Maybe [String]
testFunc f t = case apply f (replicate (arity f) t) of
Left ms -> Just ms
Right _ -> Nothing
--------------------------------------------------------------------------------