开发者

Block following this 'let' is unfinished. Expect an expression

Hi everbody I am doing a project with F# but I get this error when ı use let num= line for the following code . I'm new at F# so I can not solve the problem. My code should do this things. User enter a number and calculate the fibonacci but if user enter not a number throw exception

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 开发者_如何学CFormat Exception";
    let listFibonacci = [for i in 0 .. num-1->fib(i)]
    printFibonacci(listFibonacci)
    printfn "\n%A"(listFibonacci)
    control<-false

Console.ReadKey(true)
exit 0;;


I'm not an F# expert but I can see 3 problems with the code you posted.

1) As Lasse V Karlsen commented - f# uses the 'offside' rule so your 'fib' expression needs the body indented in. If you are running this in the Visual Studio Shell it should warn you of this by putting a blue squiggly line under the appropriate code.

2) Both 'control' and 'num' are mutable values so need to be declared explicitly as such.
f# is a functional language so by default any expressions are immutable i.e they are not allowed to change state after they have been declared.

In f#, saying 'let n = expr' does not mean 'assign the value of expr to n' like you would in say c# or c++. Instead it means 'n fundamentally is expr' and will be forever much like a mathematical equation.

So if you want to update the value of a variable you use the special '<-' notation which is the equivalent of 'assign the value on rhs to the lhs' and you need to declare that variable as mutable i.e 'this value can be changed later'

So I think both num and control need to be declared at the top of the loop as

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

As a side note you don't have to explicitly declare num as an int ( you can if you want ) but f# will infer the type for you


If I understand your code correctly, you want to keep asking for input number n until a valid number is given and print fibonacci numbers up to n. In this case, you'd better move the calculation and printing inside the try block. Here's an updated version with formatting.

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

Instead of using an imperative style number entry routine and relying on exceptions for control flow, here's a recursive getNumberFromConsole function you could use as well:

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. Thanks for showing me stdin. I never knew it existed. Now I can write some interactive scripts.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜