List 如何在F#中递归添加列表中的所有元素?

List 如何在F#中递归添加列表中的所有元素?,list,recursion,f#,element,tail-recursion,List,Recursion,F#,Element,Tail Recursion,我对F#非常陌生,所以我一直在尝试对文本文件中的所有元素(双整数)行求和,以打印出年份和元素总数 (来自文本文件的示例): 2010**(元素)->**1.07 1.56 1.74 3.84 6.8 7.89 9.2 3.46 1.67 2.22 2.49 2.81 然而,这里是我的递归函数,用于对所有元素求和。我在下面的代码中解释了主要的错误 let rec sum values:double list = if values = [] then [] els

我对F#非常陌生,所以我一直在尝试对文本文件中的所有元素(双整数)行求和,以打印出年份和元素总数

(来自文本文件的示例):

2010**(元素)->**1.07 1.56 1.74 3.84 6.8 7.89 9.2 3.46 1.67 2.22 2.49 2.81
然而,这里是我的递归函数,用于对所有元素求和。我在下面的代码中解释了主要的错误

let rec sum values:double list =
    if values = [] then
        []
    else
        values.Head + sum values.Tail

let main argv =
    // read entire file as list of strings:
    let file = ReadFile "rainfall-midway.txt"

    let (year, values) = ParseLine file.Head
    printfn "%A: %A" year (sum [values]) // values gets the error which i cannot understand at all.
错误1类型
'float list'
不支持运算符
'+'


如果您只是想完成工作,那么List.sum很简单,不会溢出堆栈

Gustavo已经有了一个很好的开始,但是如果你对很多很多值求和,你可能会溢出堆栈。您没有提到可能需要多少个值才能完成某些操作,但如果它足以使堆栈溢出,您可能希望切换到尾部递归实现(请参阅和):

通过这个实现,我可以成功地对一百万个或更多值的列表求和,而不会使堆栈溢出

如果您想进一步了解,您可以查看源代码,因为它是在列表上应用函数(甚至
(+)
)的一种更通用的方法


List.sum
的实现使用了
Seq.sum
,它显示了在序列上累加一个值,这不一定需要像
List
这样的实际容器,但这显然超出了所述问题的范围。

这一方法确实有效!比如说,我想打印出每个元素的平均值,这样行吗?let sum(values:double list)=let rec sum values acum=将值与|[]->acum | head::tail->sum tail(acum+head)/12.0求和值0.0好吧,您可能不想将其称为
sum
)您确切地知道List.length的列表中有多少项,因此无需硬编码。同样,如果你把除法从递归部分中去掉,你将除法1次而不是N次;在这种情况下,您可以在平均函数中重用求和函数。此外,还要注意围绕小数字或大数字的浮点问题(取决于您使用的值的性质和数量)。
let sum (values: double list) =

    let rec sum values accum =

        match values with
        | [] -> accum
        | head :: tail -> sum tail (accum + head)

    sum values 0.0