我正在尝试运行一个程序,但我总是在终端fib3.hs中得到这个:3:12:不在范围内:'跟踪'我不知道它是什么意思或我怎么能解决这个问题。我是一个初学者和haskell ... 我的代码
-- 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)
答案 0 :(得分:3)
错误告诉你Haskell找不到函数trace
- 问题是,它不在前奏中但在Debug.Trace
模块中,所以你必须导入它。
最简单的方法是添加
import Debug.Trace
低于module
定义(如果你有一个 - 如果不是只在文件的顶部,但是打击{-# LANGUAGE ... #-}
pragma(如果有的话)
这将从Debug.Trace
导入所有,我个人不喜欢(很难找到以这种方式定义函数的位置) - &# 39;为什么我通常更喜欢只导入所需的功能和定义(所以我可以告诉他们来自哪里)这样:
import Debug.Trace (trace)
因此,您问题的解决方案可能如下所示:
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)
...
<强>瞧强>:
λ> 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
其余的非主题,但您可能会感兴趣:
我会把它重写成:
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)
后卫 - 技巧似乎有太多 magic IMO(我显然完全错过了这一点:( ...所以你决定:我是愚蠢的还是晦涩难懂的代码?)
如果您不喜欢,那么您必须在{(1}}处前置(这是令人讨厌的是),您可以使用traceIt d n
进行修复递归:
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)