我试图在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'
为什么?
答案 0 :(得分:1)
这里有很多问题 - 但我会直接解决这个问题。
hd::tl when hd < tl
比较hd
这是一个元素,tl
是一个列表。您希望将hd
与tl
答案 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
输出与上述相同。