(请原谅我提前解决任何格式错误,因为这是我第一次在这里提出问题。)
我正在为课堂上的While语言工作,我认为我对它背后的想法以及我需要做的事情有很好的处理。我们提供了一些代码(Expr类型的eval函数),我们必须为Statement类型和赋值的符号查找功能实现eval。
我目前的问题是,在尝试执行上述操作时遇到类型错误,我不确定原因。
以下是相关代码(请注意,当前eval有意设置为= 0):
data Expr = Num Integer
| Var String
| Bin Op Expr Expr deriving Show
data Statement = Assign String Expr
| If Expr Statement Statement
| While Expr Statement
| Compound [Statement] deriving Show
env = [("n",1), ("fact", 1)]
eval (Num x) _ = x
eval (Var v) e = xlookup v e
where xlookup v ((w, x):r) | v==w = x
| otherwise = xlookup v r
eval (Bin op l r) e = kop op (eval l e) (eval r e)
where kop Mul x y = x * y
kop Sub x y = x - y
kop Add x y = x + y
kop Gt x y | x > y = 1
| otherwise = 0
eval (While exp s) e = 0
factorial = (Compound [
(Assign "n" (Num 7)),
(Assign "fact" (Num 1)),
(While (Bin Gt (Var "n") (Num 1))
(Compound [
(Assign "fact" (Bin Mul (Var "fact") (Var "n"))),
(Assign "n" (Bin Sub (Var "n") (Num 1)))
])
)
])
这是我得到的:
Hugs> :l while.hs
ERROR "while.hs":37 - Type error in function binding
*** Term : eval
*** Type : Statement -> [([Char],Integer)] -> Integer
*** Does not match : Expr -> [([Char],Integer)] -> Integer
基本上,我在一个声明的eval函数中做的每一次尝试,Haskell似乎都期待一个Expr,而我不确定为什么。我确信这是一个非常基本的问题,但不幸的是我对Haskell很新,显然还是很糟糕。谢谢你的帮助。
答案 0 :(得分:5)
您需要使eval
成为类型类的方法,我认为此时此方法过于苛刻,或者为Expr和Statement类型创建单独的eval函数:
eval_expr (Num x) = ...
eval_expr (Var x) = ...
eval_expr (Bin op l r) = ...
eval_stmt (While expr x) = ...
类型类方法如下所示:
class Eval a where
eval :: a -> [([Char], Integer)] -> Integer
instance Eval Expr where
eval (Num x) = ...
...
instance Eval Statement where
eval (While expr x) = ...
答案 1 :(得分:3)
eval
的前三个等式采用Expr
和环境,但While
是Statement
类型的构造函数。因此,您提供的定义不兼容。您可能需要两个评估函数,一个用于表达式,另一个用于语句。如果你给你的定义类型签名,你会得到更好的(如:更容易理解)错误消息。