3

Hi everbody I need to change my F# code to Haskell code but I am so new in Haskell and I can not this My code simply read data from keyboard if data not an integer return an error message then calculate the n fibonacci number then writes to a list after that writes the list into a txt file Here is my code

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 writeToFile list = 
    let file = System.IO.File.Create("C:\out2.txt")
    let mutable s =""
    let writer = new System.IO.StreamWriter(file)
    try
        for i=0 to (List.length list)-1 do
        s <- list.Item(i).ToString()
        writer.Write(s+" ")

    finally
        writer.Close()
        file.Dispose()
        printfn "Writed To File"


let mutable control = true
let mutable num = 0
while control do 
    try
    printfn "Enter a Number:" 

    num <- Convert.ToInt32(stdin.ReadLine()) 
    let listFibonacci = [for i in 0 .. num-1->fib(i)]
    printFibonacci(listFibonacci)
    printfn "\n%A"(listFibonacci)
    writeToFile(listFibonacci)
    control<-false
    with
        | :? System.FormatException->printfn "Number Format Exception";

Console.ReadKey true|>ignore
sepp2k
  • 341,501
  • 49
  • 643
  • 658
boraer
  • 319
  • 4
  • 11
  • 1
    This is covered pretty well here: http://stackoverflow.com/questions/1105765/generating-fibonacci-numbers-in-haskell – JeffH May 10 '10 at 15:33
  • 1
    Google will give you the Haskell wiki page: http://www.haskell.org/haskellwiki/The_Fibonacci_sequence that covers this in detail. – Don Stewart May 10 '10 at 18:10

2 Answers2

15
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = do putStrLn "Enter a number:"
          num <- readLn
          fibs = map fib [0..n]
          mapM' print fibs

However since haskell is lazy there is a clever way to define the list of all fibonacci numbers. And since you want a prefix of that list, it's more natural to use this definition (also more efficient):

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

main = do putStrLn "Enter a number:"
          num <- readLn
          mapM' print (take n fibs)

Edit: To write to a file instead of stdout replace print with (\num -> appendFile "filename" (show num)) or (appendFile "filename" . show).

sepp2k
  • 341,501
  • 49
  • 643
  • 658
2

That is basically the most common implementation of the sequence itself:

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

If you want the number from keyboard:

main :: IO ()
main = catch doFib handle
   where doFib = do
            num <- readLn
            putStrLn $ "Fib of " ++ show num ++ " = " ++ (show . fib $ num)
         handle _ -> putStrLn "Malformed input!"

Done!

LukeN
  • 5,284
  • 1
  • 22
  • 32
  • Are you really recommending an algorithm with a complexity of O(2^n)? It is going to be horribly slow for anything other than small values of n. – Yacoby May 10 '10 at 15:39
  • 3
    Not recommending! Just saying it's the most basic, and (most importantly here, as he is new to haskell!) easiest implementation. – LukeN May 10 '10 at 15:41
  • 4
    @Yacoby: that's an exact translation of OP's algorithm implemented in F#, so it's a translation, not a recommendation. – yairchu May 10 '10 at 20:53
  • @LukeN , using your code, I got error "error: parse error on input `->'", Im new to FP, sorry. – Jake Muller Dec 13 '16 at 05:11