在SML中使用逻辑运算符的foldr/foldl

问题描述:

我试图在SML中使用foldrfoldl建立一个函数,它将返回列表中所有元素的逻辑或逻辑。在SML中使用逻辑运算符的foldr/foldl

我试图以这种方式,使用

fun band x = foldr (op and) true x; 
fun bor x = foldr (op or) false x; 

而且还使用andalso否则别指望。不过,我不断收到错误消息,例如:

Error: unbound variable or constructor: or 

没有运营商称为SML andorand是一个关键字,用于分隔同时声明的多个变量或声明。没有or

AND和OR逻辑运算符分别为andalsoorelse,正如你在自己的答案中所说的那样,它们是短路的,而不是常规的运算符。

我发现了问题:andalsoorelse不是运营商或函数的原因,他们实现short-circuit evaluation

因此,解决方案应该是:

fun band x = foldl (fn (a,b) => a andalso b) true x; 
fun bor x = foldr (fn (a,b) => a orelse b) false x; 
+0

这并不能解释为什么'和'和'或'不工作寿。 '和'和'或'不使用短路评估,所以不应该你的第一个代码工作?免责声明:我不知道SML,但我开始阅读关于它的问题。我只是想知道区别^ _^ – naomik

+0

@naomik:'和'和'或'甚至不是运营商。 '和'是用于将相互依赖的*声明*链接在一起的关键字,例如,值声明,如相互递归函数或类型声明。即'和'不能在数值上操作。请参阅例如[什么是相互递归类型?](http://*.com/questions/14947203/what-is-a-mutually-recursive-type) –

+0

@JéssicaCarneiro:考虑使用List.all( fn x => x)'和'List.any(fn x => x)',因为它们与List.foldl不同,也是短路。在'bor'的情况下,折叠远比第一个'band'的情况下的'false'真的没有意义。 –

(回答,而不是评论。)考虑使用List.all : ('a -> bool) -> 'a list -> boolList.exists : ('a -> bool) -> 'a list -> bool因为他们是短路,不像List.foldl。折叠比band的情况下的第一个false更远,或者bor的情况下的true确实没有意义。也就是说,

val band = List.all (fn b => b) 
val bor = List.exists (fn b => b) 

一个用于这些库函数的定义中找到here

fun all p []  = true 
    | all p (x::xr) = p x andalso all p xr; 

fun exists p []  = false 
    | exists p (x::xr) = p x orelse exists p xr; 

自从被送入band名单和bor已经bool型的,经过身份功能(fn b => b)将产生理想的真值。这些函数的通用性足以适用于任何可以为每个元素应用谓词的列表,因此如果从其他列表中生成bool list,则可以避免该步骤。

+0

我提出了所有的答案,因为它们都很好,但是这个显然是最好的,正是因为'List.all'和'List.exists'短路,其中'List.foldl'没有。 – pyon

+0

这种方式更加简洁,我想我可以说它的效率更高,因为它是短路的。谢谢! –