Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean "Not in scope: ‘trace" and how can i resolve this?

I'm trying to run a program but i get always this in the terminal fib3.hs:3:12: Not in scope: ‘trace’ and i don't know what does it mean or how can i resolve this. I'm a ver beginner and haskell... my code

-- fib3.hs
fib   :: Integer -> Integer -> Integer
fib d n |  trace (shift d ++ "Call: fib " ++ show n)
                     False = 0
fib _ 0 = 0
fib _ 1 = 1
fib d n = fib (d+1) (n-1)
          + fib (d+1) (n-2)

shift :: Integer -> String
shift 0 = ""
shift n =  "   " ++ shift (n-1)
like image 389
ballenavoladora Avatar asked Dec 06 '25 07:12

ballenavoladora


1 Answers

The error is telling you that Haskell cannot find the function trace - the problem is, that it's not in the prelude but in the Debug.Trace module so you have to import this.

The easiest way to do this would be to add

import Debug.Trace 

below your module definition (if you have one - if not just at the top of the file but blow {-# LANGUAGE ... #-} pragmas (if there are any)

This will import everything from Debug.Trace which I personally don't like (it's hard to find out where a function is defined this way) - that's why I usually prefer to import only the needed functions and definitions (so I can tell where they are coming from) like this:

import Debug.Trace (trace)

So a solution to your problem could look like this:

module MyFibModule where

import Debug.Trace (trace)

-- fib3.hs
fib   :: Integer -> Integer -> Integer
fib d n |  trace (shift d ++ "Call: fib " ++ show n)
                     False = 0
fib _ 0 = 0
fib _ 1 = 1
fib d n = fib (d+1) (n-1)
          + fib (d+1) (n-2)

shift :: Integer -> String
shift 0 = ""
shift n =  "   " ++ shift (n-1)

...

voila:

λ> fib 1 4
   Call: fib 4
      Call: fib 2
         Call: fib 0
         Call: fib 1
      Call: fib 3
         Call: fib 1
         Call: fib 2
            Call: fib 0
            Call: fib 1
3

The rest is off topic but it might be interesting to you:

slight rewrite

I would rewrite this into:

fib   :: Integer -> Integer -> Integer
fib d 0 = traceIt d 0 $ 0
fib d 1 = traceIt d 1 $ 1
fib d n = traceIt d n $ fib (d+1) (n-1) + fib (d+1) (n-2)

traceIt :: Integer -> Integer -> a -> a
traceIt d n = trace (shift d ++ "Call: fib " ++ show n)

shift :: Integer -> String
shift 0 = ""
shift n =  "   " ++ shift (n-1)

the guard-trick there seems to be too much magic IMO (I obviously totally missed the point at first :( ... so you decide: am I to stupid or is the code to arcane to read?)

don't want to repeat it so much

In case you don't like that you have to prepend the traceIt d n everywhere (which is nasty yes) you can make fix the recursion with the trace:

fib :: Integer -> Integer
fib = fib' 0

fib' :: Integer -> Integer -> Integer
fib' d n = traceIt d n $ fibF (fib' (d+1)) n

fibF :: (Integer -> Integer) -> Integer -> Integer
fibF _ 0 = 0
fibF _ 1 = 1
fibF f n = f (n-1) + f (n-2)

traceIt :: Integer -> Integer -> a -> a
traceIt d n = trace (shift d ++ "Call: fib " ++ show n)

example

λ> fib 4
Call: fib 4
   Call: fib 2
      Call: fib 0
      Call: fib 1
   Call: fib 3
      Call: fib 1
      Call: fib 2
         Call: fib 0
         Call: fib 1
3
like image 123
Random Dev Avatar answered Dec 08 '25 23:12

Random Dev