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_Functional Programming - Fatal编程技术网

Debugging Haskell支持调试吗?

Debugging Haskell支持调试吗?,debugging,haskell,functional-programming,Debugging,Haskell,Functional Programming,例如,这是一个函数: iffthen :: [String] -> Parser String iffthen a = do x <- symbol (head a) y <- booleana (head (tail a)) z <- symbol (head (tail (tail a))) k <- assignP (head (tail (tail (tail a))

例如,这是一个函数:

iffthen :: [String] -> Parser String
iffthen a = do 
x <- symbol (head a)
               y <- booleana (head (tail a))
               z <- symbol (head (tail (tail a)))
               k <- assignP (head (tail (tail (tail a))))
               l <- symbol (head (tail (tail (tail (tail a)))))
               m <- assignP (head (tail (tail (tail (tail (tail a))))))
               return k
iffthen::[String]->解析器字符串
如果a=do
x您可以使用Debug.Trace的函数或类似的相关函数。如果对函数求值,此函数基本上会打印附加的
字符串
参数,并返回函数的结果

因此,对于某些可以打印的内容,我们可以附加这样的
trace
函数,从而打印信息。请注意,Haskell中的调试通常不同于命令式语言中的调试,这主要是由于惰性:除非我们需要结果,否则通常不计算函数。这意味着一些函数永远不会被计算,或者这些函数在我们构建该函数之后很久才会被计算

关于函数,我建议在这里使用模式匹配,并消除未使用变量的干扰:

iffthen :: [String] -> Parser String
iffthen (ifs : cond : thens : val1 : elses : val2 : _) = do 
    symbol ifs
    booleana cond
    symbol thens
    k <- assignP val1
    symbol elses
    assignP val2
    return k
iffthen::[String]->解析器字符串
iffthen(ifs:cond:thens:val1:elses:val2:uu)=do
符号ifs
布尔安康
符号thens

k除了
trace
,请查看
traceM::Applicative f=>String->f()
traceShowM::(显示a,Applicative f)=>a->f()

这些是在任何monad上下文中可用的
putStrLn
print
的方便替代品:

iffthen :: [String] -> Parser String
iffthen a = do 
x <- symbol (head a)
               traceM "booleana"
               y <- booleana (head (tail a))
               traceM "symbol 1"
               z <- symbol (head (tail (tail a)))
               traceM "assignP 1"
               k <- assignP (head (tail (tail (tail a))))
               traceM "symbol 2"
               l <- symbol (head (tail (tail (tail (tail a)))))
               traceM "assignP 2"
               m <- assignP (head (tail (tail (tail (tail (tail a))))))
               return k

ghci
。由于Haskell代码往往是功能性的和懒惰的,所以我认为它有时会带来惊喜。Emacs
haskell模式
过去有。。。我想我遇到了该集成作者的一条评论,指出调试器在某些方面存在问题,但我现在找不到它。但我在一些基本示例上尝试了调试器,它的效果与宣传的一样。

您有
Debug.Trace
,但由于Haskell是一种惰性语言,因此通常很难获得良好的跟踪:很多部分没有进行评估,或者在过程的后期进行评估。关于您的代码,我真的建议在这里使用模式匹配。感谢Willem Van Onsem注意,如果
[String]
参数是要解析的标记序列,那么上面的代码(或任何使用模式匹配的等效变体)在我看来是非常错误的。如果它意味着其他东西,那么这种方法可能是正确的(但看起来仍然很奇怪——列表中的字符串是什么?)。标准haskell只支持
bug
rebug
。如果您想要调试,您必须升级到。我甚至要比“从列表索引切换到模式匹配”更进一步:这些字符串应该在记录中传递,每个参数都有描述性名称。是的,但我无法立即找到函数。我假设
a1
是if_符号,然后是条件,等等。关于
trace
的事情是你需要非常清楚懒惰是如何工作的。例如,尝试
(traceM“从不打印”*>pure())()
;在第二个示例中,
x
y
z
l
m
的跟踪几乎保证不会触发,除非
解析器
在其
(>=)
实现中做了一些非常不寻常的事情,像call
seq
evaluate
或使用bang模式。另一个带有“traceM”的问题是,如果给它一个常量字符串,它将只打印一次。在此之后,编译器认为它知道表达式的计算结果是什么,并且不会再次计算它。
iffthen :: [String] -> Parser String
iffthen a = do 
x <- symbol (head a)
               y <- traceShowId <$> booleana (head (tail a))
               z <- traceShowId <$> symbol (head (tail (tail a)))
               k <- traceShowId <$> assignP (head (tail (tail (tail a))))
               l <- traceShowId <$> symbol (head (tail (tail (tail (tail a)))))
               m <- traceShowId <$> assignP (head (tail (tail (tail (tail (tail a))))))
               return k