2016-09-16 37 views
3

我試圖在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 

回答

3

沒有運營商稱爲SML andorand是一個關鍵字,用於分隔同時聲明的多個變量或聲明。沒有or

AND和OR邏輯運算符分別爲andalsoorelse,正如你在自己的答案中所說的那樣,它們是短路的,而不是常規的運算符。

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; 
+0

這並不能解釋爲什麼'和'和'或'不工作壽。 '和'和'或'不使用短路評估,所以不應該你的第一個代碼工作?免責聲明:我不知道SML,但我開始閱讀關於它的問題。我只是想知道區別^ _^ – naomik

+0

@naomik:'和'和'或'甚至不是運營商。 '和'是用於將相互依賴的*聲明*鏈接在一起的關鍵字,例如,值聲明,如相互遞歸函數或類型聲明。即'和'不能在數值上操作。請參閱例如[什麼是相互遞歸類型?](http://stackoverflow.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'真的沒有意義。 –

3

(回答,而不是評論。)考慮使用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

這種方式更加簡潔,我想我可以說它的效率更高,因爲它是短路的。謝謝! –