在SML中使用逻辑运算符的foldr/foldl
我试图在SML中使用foldr
或foldl
建立一个函数,它将返回列表中所有元素的逻辑或逻辑。在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 and
和or
。 and
是一个关键字,用于分隔同时声明的多个变量或声明。没有or
。
AND和OR逻辑运算符分别为andalso
和orelse
,正如你在自己的答案中所说的那样,它们是短路的,而不是常规的运算符。
我发现了问题:andalso
和orelse
不是运营商或函数的原因,他们实现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;
(回答,而不是评论。)考虑使用List.all : ('a -> bool) -> 'a list -> bool
和List.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
,则可以避免该步骤。
我提出了所有的答案,因为它们都很好,但是这个显然是最好的,正是因为'List.all'和'List.exists'短路,其中'List.foldl'没有。 – pyon
这种方式更加简洁,我想我可以说它的效率更高,因为它是短路的。谢谢! –
这并不能解释为什么'和'和'或'不工作寿。 '和'和'或'不使用短路评估,所以不应该你的第一个代码工作?免责声明:我不知道SML,但我开始阅读关于它的问题。我只是想知道区别^ _^ – naomik
@naomik:'和'和'或'甚至不是运营商。 '和'是用于将相互依赖的*声明*链接在一起的关键字,例如,值声明,如相互递归函数或类型声明。即'和'不能在数值上操作。请参阅例如[什么是相互递归类型?](http://*.com/questions/14947203/what-is-a-mutually-recursive-type) –
@JéssicaCarneiro:考虑使用List.all( fn x => x)'和'List.any(fn x => x)',因为它们与List.foldl不同,也是短路。在'bor'的情况下,折叠远比第一个'band'的情况下的'false'真的没有意义。 –