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

foldr/foldl with logic operators in SML

我正在尝试使用 foldrfoldl 在 SML 中构建一个函数,它将 return 列表中所有元素的逻辑 or 和逻辑 and 。

我试过这种方式,使用and and or:

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

并且还使用 andalsoorelse。但我不断收到错误消息,例如:

Error: unbound variable or constructor: or

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

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

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

(回答而不是评论。) 考虑使用 List.all : ('a -> bool) -> 'a list -> boolList.exists : ('a -> bool) -> 'a list -> bool,因为它们短路,不像 List.foldl。在 band 的情况下,折叠比第一个 falsebor 的情况下的 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;

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