【发布时间】:2020-06-07 07:08:56
【问题描述】:
我正在尝试将 where 表达式 eval 添加到我的解释器中。我目前的数据类型和评估方法如下。
data Exp = IntExp Integer
| IntOpExp String Exp Exp
| WhereExp Exp [(String, Exp)]
| VarExp String
deriving(Show,Eq)
type Env = [(String, Val)]
data Val = IntVal Integer
| ExnVal String
deriving(Show, Eq)
eval :: Exp -> Env -> Val
eval (IntExp i) _ = IntVal i
eval (IntOpExp op e1 e2) env =
let v1 = eval e1 env
v2 = eval e2 env
Just f = lookup op intOps
in liftIntOp f v1 v2
eval (LetExp var e1 e2) env =
let v1 = eval e1 env
in eval e2 (insert var v1 env)
目前,我有 where 子句的工作方式类似于 let 子句,但是对于多个表达式,因此实现了这个:
--For empty pattern (WhereExp _ []) _ :
eval (WhereExp e1 []) env = eval e1 env
--For single element case
eval (WhereExp e1 [(var, e2)]) env =
let v2 = eval e2 env
in eval e1 (insert var v2 env)
这适用于 (var,e2) 的单元素列表,例如:
ghci> eval (WhereExp (VarExp "x") [("x",(IntExp 0))]) []
(IntVal 0)
ghci> eval (IntOpExp "*" (VarExp "z") (WhereExp (IntOpExp "-" (VarExp "x") (VarExp "y")) [("y",(IntExp 5))])) [("x", (IntVal 12)), ("z", (IntVal (-4)))]
(IntVal (-28))
但不包括以下模式:
(WhereExp _ ((_, _):_:_)) _
(WhereExp _ []) _
列表中存在多个 (var,e) 元素。 例如,这种情况如下,它给出了非详尽的模式
eval((WhereExp (IntOpExp "+" (VarExp "x") (VarExp "y")) [("x",IntExp 10),("y",IntExp 12)],[]),IntVal 22)
对于如何处理 (var,e) 对列表以在我的 where 子句中实现此模式,我有点迷茫。任何帮助深表感谢!谢谢。
编辑: 根据 chi 的回答,这对我理解该做什么非常有帮助,我已经取得了一些进展,并在下面提供了我目前的状态。我使用了一个辅助函数来实现。但我似乎仍然无法涵盖模式:
(WhereExp _ ((_, _):_:_)) _
进一步的建议将不胜感激。谢谢!
helperEvaluator :: [(String,Exp)] -> Env -> [(String,Val)]
helperEvaluator xs cur_env = map (\(a,b) -> (a,eval b cur_env)) xs
eval (WhereExp e1 ((var, e2):xs)) env = eval e1 new_env
where
--helperEvaulator xs cur_env = map (\acc (a,b) -> (a,eval b cur_env)) xs
--new_list = helperEvaulator [(var, e2)] env
new_env = foldr ((\(var1,v1) -> (insert var1 v1))) (env) (helperEvaluator ((var, e2):xs) env)
【问题讨论】:
-
where中的最后三个等式必须以完全相同的方式缩进。另外,打开警告:您正在丢弃acc,应该将其报告为警告。 -
我已经修复了所有的语法问题,但仍然无法执行模式匹配。无法真正理解为什么。
-
你最后的
WhereExp模式应该涵盖除WhereExp e1 [])之外的所有情况,所以我看不出有什么问题。 -
我认为最好提出一个新的后续问题,包括最新的代码和指向此问题的链接作为背景。一次一个问题。 :)
标签: haskell functional-programming