在简单的Haskell AST中键入错误

1 haskell abstract-syntax-tree

(请原谅我提前解决任何格式错误,因为这是我第一次在这里提出问题.)

我正在为课堂上的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)))
                  ])
               )
            ])
Run Code Online (Sandbox Code Playgroud)

这是我得到的:

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
Run Code Online (Sandbox Code Playgroud)

基本上,我在一个声明的eval函数上做的每一次尝试,Haskell似乎都期待一个Expr,而我不确定为什么.我确信这是一个非常基本的问题,但不幸的是我对Haskell很新,显然还是很糟糕.谢谢你的帮助.

Tho*_*son 5

你需要创建eval一个类型类的方法,我认为这个方法过于苛刻,或者为你的Expr和Statement类型制作单独的eval函数:

eval_expr (Num x) = ...
eval_expr (Var x) = ...
eval_expr (Bin op l r) = ...

eval_stmt (While expr x) = ...
Run Code Online (Sandbox Code Playgroud)

类型类方法看起来像:

class Eval a where
    eval :: a -> [([Char], Integer)] -> Integer

instance Eval Expr where
    eval (Num x) = ...
    ...

instance Eval Statement where
    eval (While expr x) = ...
Run Code Online (Sandbox Code Playgroud)