如何使用F#中的函数找到链表的元素总和?
答案 0 :(得分:10)
F#有一个内置的“链表”(通用)类型 - 它叫做list
,并且已经有一个计算sum的函数:
let list1 = [2; 3; 5]
List.sum list1
列表上的任意操作可以使用递归函数编写:
let rec sum l =
match l with
| [] -> 0
| head::tail -> head + (sum tail)
但在大多数情况下,使用内置的fold
函数就足够了:
let sum l =
List.fold (fun total element -> total + element) 0 l
另请注意,上述“天真”递归函数不是tail-recursive,因此在应用于非常长的列表时会崩溃。尾递归实现将是这样的:
let sum l =
let rec sumAcc acc l =
match l with
| [] -> acc
| head::tail -> sumAcc (acc+head) tail
sumAcc 0 l
基本上是fold
所做的。
(我正在添加此答案,以防有人不知道F#登陆此页面 - 他/她可能对F#中的列表支持有误解)
答案 1 :(得分:1)
let rec sum a =
match a with
|Nil -> 0
|Link(s,t) -> s+(sum (!t))
答案 2 :(得分:1)
我试过你的例子,它不起作用,所以我做了修复。
type lists = Nil | Link of (int * (lists ref))
let list1 = Link(3, ref (Link (2, ref Nil)))
let list2 = Link(6, ref (Link (4, ref Nil)))
let list3 = Link(9, ref (Link (6, ref Nil)))
let rec sum = function // or let rec sum list = match list with
| Nil -> 0
| Link(head, tail) -> head + sum !tail
您无需定义Integer of int
,如果您这样做,则必须使用Integer
标记所有数字
答案 3 :(得分:1)
为了完整起见:
let sum l =
l
|> List.reduce (+)
也会做到这一点。类型推断会将l推断为int列表,因此如果您需要其他数字类型,则可以执行此操作(例如long列表):
let sum (l:list<int64>) =
l
|> List.reduce (+)
或者这个:
let inline sum l =
l
|> List.reduce (+)
内联将概括sum函数以处理任何提供名为“+”的静态函数的类型。要使用它,你需要这样的代码:
let mylist = [1;2;3;4]
let sumOfMyList = sum mylist;;
我还要说,根据我的经验,使用列表折叠和相关函数比滚动自己的递归函数更好。