比较F#中列表中的元素

时间:2015-11-13 23:01:46

标签: list f#

我试图在F#中找到列表中的最小元素。这是我的代码:

    let rec list_minl lst = 
    match lst with 
    | [] -> failwith "Empty list" 
    | hd -> hd 
    | hd::tl when hd < tl -> list_minl tl

但是当我运行程序时出现了这个错误:

FS0001: Type mismatch. Expecting a
    'a    
but given a
    'a list    
The resulting type would be infinite when unifying ''a' and ''a list'

为什么?

2 个答案:

答案 0 :(得分:1)

这里有很多问题 - 但我会直接解决这个问题。

hd::tl when hd < tl

比较hd这是一个元素,tl是一个列表。您希望将hdtl

的最小值进行比较

答案 1 :(得分:1)

正如@John Palmer在他的回答中所说,你当前的代码将类型T的元素与类型T的列表进行比较,这是不可行的。

我假设你想从数字列表中找到最小的数字。一种可能的解决方案是使用累加器作为最小值(因为你需要保留当前找到的每次迭代的最小值):

let rec list_minl lst min = 
    match lst with 
    | h1::tl when h1 > min -> list_minl tl min
    | h1::tl when h1 < min -> list_minl tl h1
    | h1::tl (* when h1 = min *) -> list_minl tl min
    | [] -> min 

累加器的初始值可以是例如列表中的第一个元素:

let lst = [10;5;2;5;100;6;3]
list_minl lst (List.head lst) |> Console.WriteLine

输出结果为:

2

你可以隐藏递归函数和初始min。 value,以便list_min只接受一个参数(列表):

let rec list_minl lst =
    let rec ilist_minl lst min = 
        match lst with
        (* if first element is bigger than current min, preserve min *)
        | h1::tl when h1 > min -> ilist_minl tl min
        (* if first element is smaller than current min, new min is current first element *)
        | h1::tl when h1 < min -> ilist_minl tl h1
        (* first element equals min, preserve min *)
        | h1::tl (* when h1 = min *) -> ilist_minl tl min
        (* processing is done *)
        | [] -> min 

    ilist_minl lst (List.head lst)

list_minl [10;5;2;5;100;6;3] |> Console.WriteLine

输出与上述相同。