Search code examples
haskellfibonacci

Printing inside of a function without changing the return type


I am trying to calculate n fibonacci numbers. This works, but i want to print every number calculated on the way to n, which seems to manipulate the return type of the function.

I'm a haskell beginner so i dont know what to search the web for.

fib n =
  case n of
    0 -> 0
    1 -> 1
    _ ->
      fib (n - 1) + fib (n - 2)

main = do
  print (fib 30)

I tried the following, after which the compiler told me im not doing it right:

import Debug.Trace

fib n =
  case n of
    0 -> 0
    1 -> 1
    _ -> do
      let r = fib (n - 1) + fib (n - 2)
      trace (show r)
      r

main = do
  print (fib 30)

The error in question:

[1 of 1] Compiling Main             ( fib.hs, fib.o )

fib.hs:13:3: error:
    • No instance for (Show (a0 -> b0)) arising from a use of ‘print’
        (maybe you haven't applied a function to enough arguments?)
    • In a stmt of a 'do' block: print (fib 30)
      In the expression: do print (fib 30)
      In an equation for ‘main’: main = do print (fib 30)
   |
13 |   print (fib 30)
   |   ^^^^^

fib.hs:13:10: error:
    • No instance for (Num (a0 -> b0)) arising from a use of ‘fib’
        (maybe you haven't applied a function to enough arguments?)
    • In the first argument of ‘print’, namely ‘(fib 30)’
      In a stmt of a 'do' block: print (fib 30)
      In the expression: do print (fib 30)
   |
13 |   print (fib 30)
   |          ^^^

Solution

  • Don't use do, do is used in monadic contexts. You can work with trace although this is merely for debugging purposes with:

    import Debug.Trace(traceShowId)
    
    fib n =
      case n of
        0 -> 0
        1 -> 1
        _ -> let r = fib (n - 1) + fib (n - 2) in traceShowId r
    
    main = print (fib 30)

    probably it is more elegant to write the patterns in the "head" of the clauses:

    import Debug.Trace(traceShowId)
    
    fib 0 = 0
    fib 1 = 1
    fib n = let r = fib (n - 1) + fib (n - 2) in traceShowId r
    
    main = print (fib 30)