with the multiple assignment (ie a,b=b,a) in f# its possible to write Fibonacci in a single line .. Can some one show how it is .. i know its possible in ruby
Longer but much faster version (via tail recursion in auxiliary function fibi
):
let fib = let rec fibi a b = function | 0 -> a | c -> fibi b (a+b) (c-1) in fibi 0I 1I
Scott Hanselman pretty much covers this in this blog post.
Here is the relevant snippet:
let rec fib n = if n < 2 then 1 else fib (n-2) + fib(n-1)
Scott got that from Dustin Cambell's blog. I post Scott's version because he also has the Ruby code for it. It's worth noting that in F#, variables are generally immutable so a,b = b,a
is not actually reassigning anything (I don't think it's even valid syntax). Rather, a function like let swap (a,b) = (b,a)
is taking a tuple and returning a new tuple with the contents reversed.
For the uninitiated, Seq.unfold is a sequence generator. It accepts as seed as input and invokes a function which returns the next element in the sequence as Some(nextElement, nextSeed)
, or None
to terminates the sequence.
It makes for a very interesting fibonacci one-liner:
> let fibs = (0L, 1L) |> Seq.unfold (fun (a, b) -> Some(a, (b, a+b)));;
val fibs : seq<int64>
> fibs |> Seq.take 50 |> Seq.toList;;
val it : int64 list =
[0L; 1L; 1L; 2L; 3L; 5L; 8L; 13L; 21L; 34L; 55L; 89L; 144L; 233L; 377L; 610L;
987L; 1597L; 2584L; 4181L; 6765L; 10946L; 17711L; 28657L; 46368L; 75025L;
121393L; 196418L; 317811L; 514229L; 832040L; 1346269L; 2178309L; 3524578L;
5702887L; 9227465L; 14930352L; 24157817L; 39088169L; 63245986L; 102334155L;
165580141L; 267914296L; 433494437L; 701408733L; 1134903170L; 1836311903L;
2971215073L; 4807526976L; 7778742049L]
let main = System.Console.WriteLine("Fibonacci")
精彩评论