简体   繁体   中英

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)

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 dn 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM