I am currently taking a class in Haskell and am having a bit of trouble understanding how functions are passed as parameters. For this assignment, we were tasked with creating a program that would evaluate expressions. To reduce boiler plating, I wanted to abstract the function by creating a helper function that would take in an operator as an input and return the result
Main Function:
eval :: EDict -> Expr -> Maybe Double
eval _ (Val x) = Just x
eval d (Var i) = find d i
eval d (Add x y) = evalOp d (+) x y
eval d (Mul x y) = evalOp d (*) x y
eval d (Sub x y) = evalOp d (-) x y
Helper Function:
evalOp:: EDict -> ((Num a) => a -> a -> a) -> Expr -> Expr -> Maybe Double
evalOp d op x y =
let r = eval d x
s = eval d y
in case (r, s) of
(Just m, Just n) -> Just (m `op` n)
_ -> Nothing
Other definitions
data Expr
= Val Double
| Add Expr Expr
| Mul Expr Expr
| Sub Expr Expr
| Dvd Expr Expr
| Var Id
| Def Id Expr Expr
deriving (Eq, Show)
type Dict k d = [(k,d)]
define :: Dict k d -> k -> d -> Dict k d
define d s v = (s,v):d
find :: Eq k => Dict k d -> k -> Maybe d
find [] _ = Nothing
find ( (s,v) : ds ) name | name == s = Just v
| otherwise = find ds name
type EDict = Dict String Double
I looked into how +,-, and * are to be passed into other functions and found that these operators are defined by the following definition:
ghci> :t (*)
(*) :: (Num a) => a -> a -> a
However, when I run my code I get the following compilation error:
Illegal polymorphic or qualified type: Num a => a -> a -> a
Perhaps you intended to use RankNTypes or Rank2Types
In the type signature for ‘evalOp’:
evalOp :: EDict
-> ((Num a) => a -> a -> a) -> Expr -> Expr -> Maybe Double
I am not really sure why this is happening as I gave my function the proper parameters as defined by Haskell. Any help would be greatly appreciated as I am still very new to the language.