I'm just starting to look into Haskell. I've written a naive Fibonacci implementation, and I've also written a more advanced one that uses tail-call recursion for efficiency.

module Fibonacci where

import System.Environment

fibonacci :: Integer -> Integer
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n
| n < 0 = error "Cannot find a negative fibonacci number"
| otherwise = fibonacci (n - 1) + fibonacci (n - 2)

fibonacci' :: Integer -> Integer
fibonacci' n
| n < 0 = error "Cannot find a negative fibonacci number"
| otherwise = fibHelper n 0 1
where
fibHelper :: Integer -> Integer -> Integer -> Integer
fibHelper n a b
| n == 0 = a
| otherwise = fibHelper (n - 1) b (a + b)

firstNumberFrom :: [String] -> Integer
firstNumberFrom [] = 10
firstNumberFrom args = read $args !! 0 main = do args <- getArgs let num = firstNumberFrom args in putStrLn$ show (fibonacci' num)


I'd appreciate any reviews on correctness and idiomatic usage.

• What is your purpose behind implementing a naive fibonacci function? Are you familiar with its the limitations? Are you familiar with more efficient fibonacci algorithms? – Code-Guru May 5 '18 at 18:47
• The Haskell wiki has an article with many different Fibonacci implementations: wiki.haskell.org/The_Fibonacci_sequence – Code-Guru May 5 '18 at 18:50

The many approaches in main and firstNumberFrom can be unified:
main = print . fibonacci' . maybe 10 read . listToMaybe =<< getArgs

The explicit recursion in fibbonacci' is captured by iterate:
fibbonacci' n = fst \$ iterate (\(a,b) -> (b, a+b)) (0,1) !! n