В настоящее время я учусь на уроке в Haskell, и у меня возникли проблемы с пониманием того, как функции передаются в качестве параметров. Для этого задания нам было поручено создать программу, которая будет оценивать выражения. Чтобы уменьшить покрытие котла, я хотел абстрагировать функцию, создав вспомогательную функцию, которая будет принимать оператор в качестве входа и возвращать результат
Основная функция:
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
Вспомогательная функция:
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
Другие определения
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
Я рассмотрел, как +, - и * должны передаваться в другие функции, и обнаружил, что эти операторы определены следующим определением:
ghci> :t (*)
(*) :: (Num a) => a -> a -> a
Однако, когда я запускаю свой код, я получаю следующую ошибку компиляции:
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
Я не совсем уверен, почему это происходит, поскольку я дал своей функции правильные параметры, как определеноХаскеллом. Любая помощь будет принята с благодарностью, так как я все еще плохо знаком с языком.