まず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
コードの2番目の問題は、要素を追加して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)