在F#中应用折叠功能

时间:2015-11-16 21:41:39

标签: list f# fold

 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:类型'(' a - >' b)'不支持比较'约束。例如,它不支持“System.IComparable”'接口

为什么呢?请帮忙:(

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

像往常一样Tomas的答案是现场,所以我只有一个小小的评论:

你可能已经看到尝试找到空列表的最小值是没有意义的(所以函数可能应该是'a option类型,当你有一个非空列表时它非常易于使用List.reduce(对于二进制操作基本上只是foldmin是这种操作的理想选择):

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

好吧,这是一个公平的问题,关于 fold - 所以如果它必须完全List.fold你当然可以做(正如TheInnerLight评论的那样):

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