大家好我正在用F#做一个项目但是当我使用let num = line代替以下代码时我得到了这个错误。我是F#的新手,所以我无法解决问题。我的代码应该做这件事。用户输入一个数字并计算斐波纳契,但如果用户输入的数字不是抛出异常
open System
let rec fib n =
match n with
|0->0
|1->1
|2->1
|n->fib(n-1)+fib(n-2);;
let printFibonacci list =
for i=0 to (List.length list)-1 do
printf "%d " (list.Item(i));;
let control = true
while control do
try
printfn "Enter a Number:"
let num:int = Convert.ToInt32(stdin.ReadLine())
with
| :? System.FormatException->printfn "Number Format Exception";
let listFibonacci = [for i in 0 .. num-1->fib(i)]
printFibonacci(listFibonacci)
printfn "\n%A"(listFibonacci)
control<-false
Console.ReadKey(true)
exit 0;;
答案 0 :(得分:8)
我不是F#专家,但我发现您发布的代码存在3个问题。
1)正如Lasse V Karlsen评论的那样 - f#使用'越位'规则,因此你的'fib'表达式需要缩进主体。如果你在Visual Studio Shell中运行它,它应该通过蓝色警告你在适当的代码下的波浪线。
2)'control'和'num'都是可变值,因此需要明确声明 f#是一种函数式语言,因此默认情况下,任何表达式都是不可变的,即它们在声明后不允许更改状态。
在f#中,说'let n = expr'并不意味着'将expr的值赋给n',就像你说c#或c ++一样。相反,它意味着'从根本上说是 expr'并且将永远像一个数学方程式。
因此,如果你想更新变量的值,你可以使用特殊的'&lt; - '表示法,它相当于'将rhs上的值赋给lhs',你需要将该变量声明为可变的,即'这个值可以在以后更改'
所以我认为num和control都需要在循环的顶部声明为
let mutable control = false
let mutable num = 0 // or whatever you want the initial value of num to be
作为附注,您不必将num显式声明为int(如果需要,可以使用),但f#将推断出类型
答案 1 :(得分:3)
如果我正确理解您的代码,您需要继续询问输入数字n,直到给出有效数字并将fibonacci数字打印到n。在这种情况下,您最好在try块内移动计算和打印。这是一个带格式的更新版本。
open System
let rec fib n =
match n with
|0->0
|1->1
|2->1
|n->fib(n-1)+fib(n-2);;
let printFibonacci list =
for i=0 to (List.length list)-1 do
printf "%d " (list.Item(i))
let mutable control = true //you forgot to add the 'mutable' keyword
while control do
try
printfn "Enter a Number:"
let num:int = Convert.ToInt32(stdin.ReadLine())
let listFibonacci = [for i in 0 .. num-1 -> fib(i)]
printFibonacci(listFibonacci)
printfn "\n%A"(listFibonacci)
control <- false
with
| :? System.FormatException -> printfn "Number Format Exception"
//add the ignore statement to drop the resulting ConsoleKeyInfo struct
//or the compiler will complain about an unused value floating around.
Console.ReadKey(true) |> ignore
// exit 0 (* Exit isn't necessary *)
除了使用命令式样式号输入例程并依赖控件流的异常外,还可以使用递归的getNumberFromConsole函数:
open System
let rec fib n =
match n with
| 0 -> 0
| 1 | 2 -> 1
| n -> fib(n-1) + fib(n-2);;
let printFibonacci list =
for i=0 to (List.length list)-1 do
printf "%d " (list.Item(i))
//alternative number input, using recursion
let rec getNumberFromConsole() =
match Int32.TryParse(stdin.ReadLine()) with
| (true, value) -> value
| (false, _) -> printfn "Please enter a valid number"
getNumberFromConsole()
printfn "Enter a Number:"
let num = getNumberFromConsole()
let listFibonacci = [for i in 0 .. num-1 -> fib(i)]
printFibonacci(listFibonacci)
printfn "\n%A"(listFibonacci)
Console.ReadKey(true) |> ignore
P.S。谢谢你给我看stdin
。我从来不知道它存在。现在我可以编写一些交互式脚本。