我試圖在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中使用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://stackoverflow.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'真的沒有意義。 –