Mar*_*van 3 testing debugging haskell
我正在玩代码大战来提高我的Haskell技能,并遇到一个我在命令式语言中没有的问题.
假设我在javascript中编写一个函数foo(),它接受一个int,加两个,正方形,减去一个,然后返回该数字的平方根.
var foo = function(n) {
n += 2;
n = n * n;
n -= 1;
n = Math.sqrt(n);
}
Run Code Online (Sandbox Code Playgroud)
我想在各个点检查函数中正在处理的数据的状态,以帮助我排除故障/修改/调试代码,所以每当我想看看我在哪里时,我都会插入console.log()语句.例如,我实际上是在函数的正中途正确地计算n + 2的总和吗?让我们来看看...
var foo = function(n) {
n += 2;
n = n * n;
console.log("n = " + n);
n -= 1;
n = Math.sqrt(n);
}
Run Code Online (Sandbox Code Playgroud)
虽然这个例子应该足够简单,以便Haskeller能够在一行中写入,但如果你有一个复杂的函数并想要在不同的点检查状态,那么Haskellers如何做呢?是否有使用IO()monad的标准做法?他们是否以其他方式绕过它?
GHCi有一个花哨的调试器,它允许您逐步执行代码并逐行评估它,检查它的状态和中间结果.
但是,当然printf
,使用trace
函数from 还有你要求的样式调试Debug.Trace
.将它用于小脚本imho没有错,但通常不鼓励.
trace
有类型String -> a -> a
,所以你传递一个被打印的字符串(via unsafePerformIO
)和任何简单返回的参数.
在您的示例中,我们可以按如下方式使用它.这是你的功能翻译成Haskell:
foo x = sqrt $ (x+2)**2 - 1
Run Code Online (Sandbox Code Playgroud)
现在我们可以添加trace
和我们想要看到的字符串,例如"Debug Me: " ++ (show ((x+2)**2))
.首先导入Debug.Trace
:
import Debug.Trace
foo x = sqrt $ (trace ("Debug Me: " ++ (show ((x+2)**2))) ((x+2)**2)) - 1
Run Code Online (Sandbox Code Playgroud)
有点难看?根据David Young在下面的评论traceShowId :: Show a => a -> a
,如果我们想要输出的内容与中间结果相同(String
当然转换为),我们会更好地使用:
import Debug.Trace
foo x = sqrt $ (traceShowId ((x+2)**2)) - 1
Run Code Online (Sandbox Code Playgroud)
有关调试选项的摘要,请参见此处.
归档时间: |
|
查看次数: |
195 次 |
最近记录: |