2013-04-29 43 views

回答

1
let rec sum a = 
    match a with 
    |Nil -> 0 
    |Link(s,t) -> s+(sum (!t)) 
+0

我不认为你可以有一个'_'被允许在模式匹配中,对吧?你有_ +(sum(!t)) – 2013-04-29 22:39:03

+0

@JohnOriely我改变它只是为了确定,已经测试它,它的工作原理 – 2013-04-29 22:56:19

+0

我实际上错误地键入了错误的声明,这就是为什么它不工作。你能再看一次吗,谢谢! – 2013-04-29 23:02:18

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

+0

嗯有趣,当我尝试这个时,它说'h'和'sum!t'类型不匹配 – 2013-04-29 22:49:32

+0

它适用于我。你确定?从头开始尝试代码,我只是重命名了一些变量。 – Gustavo 2013-04-29 22:51:31

+0

啊我在声明时输入的行不正确。类型rNumber = int的整数;; type lists =无| (rNumber *(lists ref))的链接它假设是“rNumber”不是整数。这就是为什么我得到一个错误,说明'int'类型不匹配'rNumber'。我将如何解决这个问题?感谢您一直以来的帮助! – 2013-04-29 23:01:32

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

只是为了完整起见:

let sum l = 
    l 
    |> List.reduce (+) 

也会诀窍。类型推断将推断l至是int列表,所以如果你需要一些其他数据类型,你可以这样做(例如多头列表):

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;; 

我还要说,在我的经验,使用列表褶皱和相关的功能比滚动自己的递归函数的更好方法。