Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Debugging 如何调试Haskell代码?_Debugging_Haskell - Fatal编程技术网

Debugging 如何调试Haskell代码?

Debugging 如何调试Haskell代码?,debugging,haskell,Debugging,Haskell,我有个问题。我写了一个大的Haskell程序,它总是在小的输入下工作。现在,当我想测试它并生成更大的输入时,我总是得到这样的信息: HsProg: Prelude.head: empty list 我多次使用Prelude.head。我可以做些什么来发现更多的错误或获得更好的错误输出,以获得发生错误的代码行?您可能想看一看,其中包含许多解决问题的有用方法 一个很有希望的工具是,它将帮助您找到触发空列表错误的代码中的head调用 就我个人而言,我建议使用该软件包,它允许注释前奏曲中的大部分部分函

我有个问题。我写了一个大的Haskell程序,它总是在小的输入下工作。现在,当我想测试它并生成更大的输入时,我总是得到这样的信息:

HsProg: Prelude.head: empty list

我多次使用
Prelude.head
。我可以做些什么来发现更多的错误或获得更好的错误输出,以获得发生错误的代码行?

您可能想看一看,其中包含许多解决问题的有用方法

一个很有希望的工具是,它将帮助您找到触发空列表错误的代码中的
head
调用


就我个人而言,我建议使用该软件包,它允许注释前奏曲中的大部分部分函数(从而导致更自觉地使用这些部分函数),或者更好地使用函数的总变体,例如
head
,它总是返回一个结果(如果至少定义了输入值).

GHCi选项
-fbreak on exception
可能很有用。下面是一个调试会话的示例。首先,我们将文件加载到GHCi中

$ghci breaked.hs
GHCi,7.0.2版:http://www.haskell.org/ghc/  :? 求救
正在加载程序包ghc prim。。。链接。。。完成。
正在加载包整型gmp。。。链接。。。完成。
正在加载包库。。。链接。。。完成。
正在加载包ffi-1.0。。。链接。。。完成。
[1/1]编译Main(break.hs,已解释)
好的,模块已加载:Main。
现在,我们打开
-fbreak on exceptions
并跟踪我们的表达式(
main
,本例中为整个程序)

*Main>:设置-fbreak on异常
*Main>:跟踪Main
停在
_异常::e=_
我们遇到了一个例外。让我们试着用
:list
查看代码

[]*Main>:列表
无法列出的源
尝试:返回:列表
因为异常发生在
Prelude.head
中,所以我们不能直接查看源代码。但正如GHCi通知我们的那样,我们可以返回并尝试在跟踪中列出之前发生的事情

[]*Main>:返回
断开时记录的断点。hs:2:23-42
_结果::[整数]
[-1:breaked.hs:2:23-42]*Main>:列表
1.
2 main=print$head$过滤奇数[2,4,6]
3.
在终端中,有问题的表达式
过滤奇数[2,4,6]
以粗体突出显示。这就是在本例中计算为空列表的表达式


有关如何使用GHCi调试器的详细信息,请参阅。

自GHC 8以来,您可以使用GHC.Stack模块或一些详细的评测编译器标志。

您可以使用此库:

您可以使用函数替换任何值a:

trace::String->a->a

putStrLn
不同,输出中没有
IO
,例如:

>>> let x = 123; f = show
>>> trace ("calling f with x = " ++ show x) (f x)
calling f with x = 123
123

跟踪功能只能用于调试或监视执行。该函数不是引用透明的:其类型表示它是纯函数,但它有输出跟踪消息的副作用。

您使用的是什么Interpeter或编译器?希望这将帮助您[如何使用printfs“调试”Haskell?][1][1]:这并不是您问题的答案,但是你应该考虑重构你的代码。首先,使用
head
听起来似乎是个坏主意。不要使用
head
,这是个坏主意。正如您刚才所注意到的,如何使用安全版本的
head
可能值得单独提一个问题。尽管您可能不想使用任何一种版本,而是坚持使用模式匹配。首先,我建议不要使用
head
,尤其是对于不熟悉该语言的人。@camccann我完全同意。。。唉,我所看到的大多数介绍性材料(包括相当现代的LYAH)都是从解释
head
开始的,只是警告不要将其应用于空列表…:-/如果按照我的方式,我会将它(连同
尾部
(!!)
,以及其他一些东西)从
前奏曲
中完全删除,并且从不向初学者提及它。但是哦,好吧。@hvr,
loch
无法在ghc7中构建<代码>泰晤士河对我来说很有用。但它似乎没有像loch那样的预处理器支持。你的loch链接给了我一个403错误,但我想是同一个工具吗?太棒了。我没有寻找有关GHCi调试器的信息,但这真的很酷。-异常时fbreak已更改为错误时fbreak。@PetrGladkikh 404