【问题标题】:Implementing where expression to haskell interpreter将 where 表达式实现到 haskell 解释器
【发布时间】: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


【解决方案1】:

我会假设 where 绑定不能像您的 let 那样递归。

所以,我们有WhereExp e1 bindings,其中bindings :: [(String, Exp)]。我们可以如下进行。

  • 首先,我们递归地评估该列表中的所有Exps。我们可以为此使用map ... bindings,其中... 函数适当地调用eval。这会生成一个评估绑定列表[(String, Val)]
  • 然后,我们必须将insert 这些值写入env。也就是说,我们要从列表[(str1, val1), (str2, val2), ...] 中计算insert str1 val1 (insert str2 val2 .... env)
  • 最后,使用修改后的环境,我们可以评估e1

【讨论】:

  • 根据您的回答,我明白了该怎么做,这非常有帮助。谢谢。但是由于语法问题,我现在很难实现它。你能看看我的进展并提供一些见解吗?再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 2023-03-27
相关资源
最近更新 更多