2010-05-09 32 views
1

你好,我正在用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

請檢查格式並在必要時進行更正,我對F#不熟悉足以確定哪些部分應該正確縮進。我所做的只是縮進代碼4個空格,以便讓SO代碼格式化系統起作用。 – 2010-05-09 10:46:55

回答

8

我不是F#專家,但我可以看到3個問題與你發佈的代碼。 1)作爲Lasse V Karlsen評論 - f#使用'越位'規則,所以你的'纖維'表達需要身體縮進。如果你在Visual Studio Shell中運行它,它應該通過將根據相應的代碼藍色波浪線。 2)'control'和'num'都是可變值,因此需要明確聲明。
f#是一種功能語言,因此默認情況下,任何表達式都是不可變的即它們在聲明後不允許更改狀態。在f#中,說'let n = expr'並不意味着'將expr的值賦值給n',就像你會說c#或C++一樣。相反,它意味着'從根本上說, expr',並且將永遠像一個數學方程式。

所以,如果你想更新變量的值,你使用特殊的'< - '符號,它相當於'將rhs的值賦給lhs',你需要聲明該變量爲可變的,即'這個值以後可以更改」

所以我覺得這兩個NUM和控制需要在循環的頂部聲明爲

let mutable control = false 
let mutable num = 0 // or whatever you want the initial value of num to be 

作爲一個側面說明你沒有明確聲明NUM爲一個int(你可以如果你想)但f#會推斷你的類型

+0

非常感謝zebrabox – boraer 2010-05-09 17:29:26

+0

@boraer - 如果斑馬的答案幫助了你,請繼續並接受答案。 :-) – JasCav 2010-12-08 16:30:29

3

如果我正確理解你的代碼,你想繼續詢問輸入數字n,直到給出一個有效的數字並打印斐波那契數字爲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 

附:感謝您給我看stdin。我從來不知道它存在。現在我可以編寫一些交互式腳本。

+3

聖潔的廢話! 'stdin'!我需要去更新我所有的代碼高爾夫! :) – Brian 2010-05-09 17:00:53

+0

謝謝大家:-) – boraer 2010-05-09 17:29:05

相關問題