calculator-0.2.0.0: src/Calculator/Prim/Function.hs
module Calculator.Prim.Function
( Function
, apply
, mkFunc
, mkFuncEither
, oneArg
, partial
) where
--------------------------------------------------------------------------------
-- | Represents a function, where rank == No. of arguments
data Function a = Function {
arity :: Int
, apply :: [a] -> Either [String] a
}
--------------------------------------------------------------------------------
-- | Make a @Function@ out of an arity and another function
mkFunc :: Int -> ([a] -> a) -> Function a
mkFunc a f = mkFuncEither a (Right . f)
--------------------------------------------------------------------------------
-- | Make a @Function@ with an arity using an error giving function
mkFuncEither :: Int -> ([a] -> Either [String] a) -> Function a
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 :: (a -> a) -> Function a
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 a -> [a] -> a -> Maybe a
partial f xs x = case apply f (x:xs) of
Left _ -> Nothing
Right v -> Just v
--------------------------------------------------------------------------------