Haskell中的短路布尔二元算子

Haskell中的短路布尔二元算子,haskell,boolean,interpreter,short-circuiting,Haskell,Boolean,Interpreter,Short Circuiting,我正在构建一个名为Haskell解释器的调用,我想实现一个函数short::Val->Exp->Error Val,该函数将计算应用于表达式的值。我不想计算短路布尔二进制运算符的第二个参数(即(&&&&)False)和((| |)True)),也不想计算传递给单位lambda(\()->…)抽象的参数 在Haskell这样的惰性语言中,我知道Prelude中内置了短路布尔二进制运算符。我在想这样做是可能的: short :: Val -> Exp -> Error Val short

我正在构建一个名为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

函数参数的计算首先由用于绑定参数的模式确定

如果你有

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
这样做不起作用,因为
False
Bool
而不是
Val
,您可以使用

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

假设构造函数
操作
。(您可以在那里使用
(&&&)
,但这是一个与任何内容都匹配的变量模式。)该模式甚至不绑定
Exp
参数,因此除非前面的
short
公式强制对其求值,它仍然未计算。

函数参数的计算首先由用于绑定参数的模式确定

如果你有

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
这样做不起作用,因为
False
Bool
而不是
Val
,您可以使用

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

假设构造函数
操作
。(您可以在那里使用
(&&&)
,但这是一个与任何内容都匹配的变量模式。)该模式甚至不绑定
Exp
参数,因此除非前面的
short
公式强制对其求值,否则它将保持未求值状态。

您能提供更多的代码吗,比如
Val
Exp
是如何定义的。这没什么可谈的。代码让我们几乎不知道你想在那里做什么。为什么要在这里使用
&&
作为模式?忽略
(&&&)False)
在语法上不是合法模式这一事实,
&&
是Haskell的操作符,而不是您的语言。您不应该与您的语言的&&运算符的任何表示形式进行匹配吗?对此感到抱歉。我已经包括了
Val
Exp
的定义。您能否提供更多的代码,比如
Val
Exp
是如何定义的。这没什么可谈的。代码让我们几乎不知道你想在那里做什么。为什么要在这里使用
&&
作为模式?忽略
(&&&)False)
在语法上不是合法模式这一事实,
&&
是Haskell的操作符,而不是您的语言。您不应该与您的语言的&&运算符的任何表示形式进行匹配吗?对此感到抱歉。我已经包含了
Val
Exp
的定义,感谢您的详细解释!谢谢你的详细解释!