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

How do I add all elements from a list in F# recursively?

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

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

2010    **(the elements)->** 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.

Error 1 The type 'float list' does not support the operator '+'

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

Gustavo 开局不错,但如果您要对很多很多值求和,您可能会溢出堆栈。你没有提到你可能需要多少值,但如果它足以溢出堆栈,你会想要切换到尾递归实现(参见 tail call and F# Tail Recursive Function Example):

let sum (values: double list) =

    let rec sum values accum =

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

    sum values 0.0

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

如果您想进一步了解您的理解,您可以查看 List.fold 的源代码,因为它是一种将函数(甚至 (+))应用于列表。

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