首先,您使用let
的好像它是一个改变变量的语句,但事实并非如此。在 F# 中,let
用于声明一个新值(可能隐藏任何以前的同名值)。如果你想使用突变编写代码,那么你需要使用类似的东西:
let c = a + b // declare new local value
l.Add(c)
a <- b // mutate value marked as 'mutable'
b <- c // .. mutate the second value
您的代码的第二个问题是您试图通过向其添加元素来改变 F# 列表 - F# 列表是不可变的,因此一旦创建它们,就无法修改它们(特别是没有Add
成员!)。如果你想用变异来写这个,你可以写:
let fabList =
// Create a mutable list, so that we can add elements
// (this corresponds to standard .NET 'List<T>' type)
let l = new ResizeArray<_>([1;2])
let mutable a = 1
let mutable b = 2
while l.[l.Count - 1] < 400 do
let c = a + b
l.Add(c) // Add element to the mutable list
a <- b
b <- c
l |> List.ofSeq // Convert any collection type to standard F# list
但是,正如其他人已经指出的那样,以这种方式编写代码并不是惯用的 F# 解决方案。在 F# 中,您将使用不可变列表和递归而不是循环(例如while
)。例如像这样:
// Recursive function that implements the looping
// (it takes previous two elements, a and b)
let rec fibsRec a b =
if a + b < 400 then
// The current element
let current = a + b
// Calculate all remaining elements recursively
// using 'b' as 'a' and 'current' as 'b' (in the next iteration)
let rest = fibsRec b current
// Return the remaining elements with 'current' appended to the
// front of the resulting list (this constructs new list,
// so there is no mutation here!)
current :: rest
else
[] // generated all elements - return empty list once we're done
// generate list with 1, 2 and all other larger fibonaccis
let fibs = 1::2::(fibsRec 1 2)