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

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

问题描述

我刚刚开始使用 VS2010 学习 F#,下面是我第一次尝试生成斐波那契数列.我想要做的是建立一个所有小于 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 用于声明一个新值(它可能隐藏任何以前的同名值).如果你想使用mutation来编写代码,那么你需要使用类似的东西:

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# 列表 - F# 列表是不可变的,因此一旦创建它们,您就无法修改它们(特别是,没有 添加 成员!).如果你想用mutation来写这个,你可以写:

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天全站免登陆