2015-11-16 50 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