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

时间:2016-09-16 18:31:40

标签: functional-programming sml fold ml

我尝试使用foldrfoldl在SML中构建一个函数,它将返回列表中逻辑或逻辑以及所有元素。

我已经尝试过这种方式,使用以及

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

还使用 andalso orelse 。但我一直收到错误信息,例如:

Error: unbound variable or constructor: or

3 个答案:

答案 0 :(得分:4)

(答案而不是评论。)考虑使用List.all : ('a -> bool) -> 'a list -> boolList.exists : ('a -> bool) -> 'a list -> bool,因为它们与List.foldl不同,因为它们会短路。折叠比false的情况下的第一个bandtrue的情况中的bor折叠更为重要。也就是说,

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;

由于提供给bandbor的列表已经是bool类型,因此传递标识函数(fn b => b)将生成所需的真值。这些函数非常通用,可以处理任何类型的列表,您可以为每个元素应用谓词,因此如果您从其他列表生成bool list,则可以避免该步骤。

答案 1 :(得分:3)

我发现了问题: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;

答案 2 :(得分:3)

SML中没有名为andor的运算符。 and是用于分隔同时声明的多个变量或声明的关键字。没有or

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