在F#中生成斐波那契数列 [英] Generating Fibonacci series in F#

查看:74
本文介绍了在F#中生成斐波那契数列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用VS2010学习F#,下面是我第一次尝试生成Fibonacci系列的知识.我想做的是建立一个小于400的所有数字的列表.

I'm just starting to learn F# using VS2010 and below is my first attempt at generating the Fibonacci series. What I'm trying to do is to build a list of all numbers less than 400.

let fabList = 
    let l =  [1;2;]
    let mutable a = 1
    let mutable b = 2
    while l.Tail < 400 do
        let c = a + b
        l.Add(c)
        let a = b
        let b = c

我的第一个问题是,在最后一条语句上,我在最后一行收到一条错误消息表达式中此点或之前的不完整结构化构造".我不明白我在做什么错.

My first problem is that on the last statement, I'm getting an error message "Incomplete structured construct at or before this point in expression" on the last line. I don't understand what I'm doing wrong here.

虽然这似乎是一种以相当有效的方式(从c ++/C#程序员那里)构建列表的明显方法,但据我对f#所知甚少,但这似乎并不是正确的方法.做程序.我在这种感觉上是正确的吗?

While this seems to be an obvious way to build the list in a fairly efficient way (from a c++/C# programmer), from what little I know of f#, this doesn't seem to feel to be the right way to do the program. Am I correct in this feeling?

推荐答案

首先,您正在使用let,就好像它是对变量进行突变的语句一样,但事实并非如此.在F#中,let用于声明一个新值(它可能隐藏相同名称的所有先前值).如果您想使用变异来编写代码,则需要使用类似以下内容的

First of all, you're using let as if it was a statement to mutate a variable, but that's not the case. In F#, let is used to declare a new value (which may hide any previous values of the same name). If you want to write code using mutation, then you need to use something like:

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成员!).如果您想使用变异来编写此代码,则可以编写:

The second issue with your code is that you're trying to mutate F# list by adding elements to it - F# lists are immutable, so once you create them, you cannot modify them (in particular, there is no Add member!). If you wanted to write this using mutation, you could write:

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).例如这样的

But, as others already noted, writing the code in this way isn't the idiomatic F# solution. In F#, you would use immutable lists and recursion instead of loops (such as while). For example like this:

// 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)

这篇关于在F#中生成斐波那契数列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆