Haskell中的短路布尔二进制运算符

时间:2012-12-03 06:00:36

标签: haskell boolean interpreter short-circuiting

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

在像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

1 个答案:

答案 0 :(得分:4)

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

如果你有

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,则exp仅在something中使用时进行评估,并且评估something时需要进行评估。仅当前两个条件评估为False时,才会评估ex以确定第三个警卫的值(当时可能不会)。

如果你可以根据val的构造函数进行快捷方式,你可以使用val的可反射模式,让ex成为变量模式(只是一个标识符),你得到了与(&&)等相同的短路。

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

使用OR的假设构造函数Oper。 (你可以在那里使用(&&),但这是一个匹配任何东西的变量模式。)该模式甚至不绑定Exp参数,所以除非它的评估是由{{1它仍然没有评估。