【问题标题】:Short-circuited boolean binary operators in HaskellHaskell中的短路布尔二元运算符
【发布时间】:2012-11-20 14:33:29
【问题描述】:

我正在构建一个名为 Haskell 解释器的调用,并且我想实现一个函数 short :: Val -> Exp -> Error Val,它将评估应用于表达式的值。我不想评估短路布尔二元运算符的第二个参数(即((&&) False)((||) True)),也不想评估传递给单元 lambda (\() -> ...) 抽象的参数。

在像 Haskell 这样的惰性语言中,我知道您会在 Prelude 中内置短路布尔二元运算符。我在想它可以做这样的事情:

short :: Val -> Exp -> Error Val
short (Partial (&&) False) = False
-- Making use of Partial Oper Val that is defined in Val

但我已经知道会出现类型错误。我不确定该怎么做。有什么建议吗?

一些额外的定义:

data Val = VUnit | VNil
         | VN Int | VB Bool | VOp Oper
         | Partial Oper Val
         | VLamUnit Exp (Env Val)
         | VLam String Exp (Env Val)
         | VListBool [Bool]
         | VListInt [Int]

data Exp = Unit | Nil
         | N Int | B Bool | Var String | Op Oper
         | App Exp Exp
         | LamUnit Exp
         | Lam String Exp
         | If Exp Exp Exp
         | Let [(String, Exp)] Exp

data Error a = S a
             | Error String

【问题讨论】:

  • 您能否提供更多代码,例如如何定义ValExp。这没什么好继续的。
  • 该代码让我们对您在那里尝试做的事情知之甚少。为什么在这里使用&& 作为模式?忽略((&&) False) 不是语法合法模式这一事实,&& 是 Haskell 的运算符,而不是您的语言。你不应该匹配你的语言的 && 运算符的任何表示吗?
  • 对此感到抱歉。我已经包含了ValExp 的定义

标签: haskell boolean interpreter short-circuiting


【解决方案1】:

函数参数的评估首先由用于绑定参数的模式确定。

如果你有

short :: Val -> Exp -> Error Val
short val ex
   | condition on val only       = something
   | other condition on val only = somethingElse
   | condition involving ex too  = thirdPossibility
   | otherwise                   = whatever

在绑定参数时不会进行评估,因为模式是无可辩驳的变量模式,val 被 - 部分或可能完全 - 评估以确定第一个守卫的结果。如果计算结果为True,则仅在something 中使用exp 时才对其进行评估,并且评估something 是必需的。只有当前两个条件评估为 False 时,才会评估 ex 以确定第三个守卫的值(甚至可能不是这样)。

如果您可以基于val 的构造函数进行快捷方式,则可以对val 使用可反驳的模式并让ex 成为变量模式(只是一个标识符),您将获得与for 相同的短路(&&)

short (Val foo) ex = Okay (foo bar ex)
short (Lav oof) _  = Okay oof
short val ex
  | isGood val = oomph
  | isBad ex   = error "Didn't expect that"
  | otherwise  = undefined

如果你不使用右边的Exp参数,你甚至不需要给它一个名字,通配符_表示“这是一个应该被忽略的参数”。

为了你想要的行为

short :: Val -> Exp -> Error Val
short (Partial (&&) False) = False

这样不起作用,因为FalseBool 而不是Val,您可以使用

short (Partial OR (VB False)) _ = S False

使用Oper 的假设构造函数OR。 (您可以在那里使用(&&),但这是一个匹配任何东西的变量模式。)该模式甚至不绑定Exp 参数,因此除非它的评估已被先前的short 等式强制,否则它仍然未评估.

【讨论】:

  • 感谢详细解释!
猜你喜欢
  • 2020-04-02
  • 2011-08-04
  • 2014-05-31
  • 2011-12-26
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多