2015-11-16 96 views
2
let list_min_fold = List.fold (fun acc -> List.min acc) 0 lst 
    printfn"Using regular List.fold function:\n  The minimum is: %A\n" 
     (list_min_fold) 

當我執行我的代碼此錯誤顯示: 錯誤FS0001:類型「(」一 - >「B)」不支持「比較」約束。例如,它不支持'System.IComparable'接口應用摺疊功能在F#

爲什麼?請幫助:(

回答

2

你試圖找到在列表中最小的數字。如果是這樣,你需要使用min函數(只需要兩個參數),而不是List.min(這需要的參數列表):

爲了保持代碼的最相似的例子,你可以寫(另請注意,開始與0是行不通的,所以我用System.Int32.MaxValue代替):

let lst = [4;3;1;2;5;] 
let list_min_fold = List.fold (fun acc -> min acc) System.Int32.MaxValue lst 

還值得一提的是,您傳遞給fold的函數需要兩個參數 - 狀態acc和當前值:

let list_min_fold = List.fold (fun acc v -> min acc v) System.Int32.MaxValue lst 

但由於部分功能的應用程序,你可以省略其中的一個(像你一樣),或者兩者:

let list_min_fold = List.fold min System.Int32.MaxValue lst 
+0

我建議'讓listMinFold = List.fold min(List.head lst)lst'。 'lst = []'時返回'System.Int32.MaxValue'可能不好。 – TheInnerLight

+0

@TheInnerLight在這種情況下,你可以只使用'List.reduce';} – Carsten

+0

@Carsten絕對正確,但問題是關於'fold'。儘管如此,這可能也值得一提。 – TheInnerLight

2

一如既往托馬斯的回答是點上所以我只有一個小小的評論:

正如你可能看到它試圖找到一個空列表的最小值沒有意義(所以函數可能應該是'a option類型,並且當你有一個非空列表時,它是很容易使用List.reduce(這是ba sically只是二進制運算和min一個fold是進行這種操作的最佳候選):

let list_min xs = 
    match xs with 
    | [] -> None 
    | _ -> List.reduce min xs 
      |> Some 

這樣你會得到:

> list_min [2;1;5;3];; 
val it : int option = Some 1 
> list_min [2;1;5;3;0];; 
val it : int option = Some 0 
> list_min ([] : int list);; 
val it : int option = None 

確定這是一個公平一點,問題是約 - 所以如果它必須是List.fold你當然可以(如TheInnerLight所述):

let list_min xs = 
    match xs with 
    | []  -> None 
    | (x::xs) -> List.fold min x xs 
       |> Some 
+0

我確實喜歡使用'Some' /'None'作爲最低限度處理空列表的建議,特別是如果你期望得到它們。有時,標準庫中的'List.tryMin'可能會很方便。 – TheInnerLight