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代码往往是功能性的和懒惰的,所以我认为它有时会带来惊喜。Emacshaskell模式
过去有。。。我想我遇到了该集成作者的一条评论,指出调试器在某些方面存在问题,但我现在找不到它。但我在一些基本示例上尝试了调试器,它的效果与宣传的一样。您有Debug.Trace
,但由于Haskell是一种惰性语言,因此通常很难获得良好的跟踪:很多部分没有进行评估,或者在过程的后期进行评估。关于您的代码,我真的建议在这里使用模式匹配。感谢Willem Van Onsem注意,如果[String]
参数是要解析的标记序列,那么上面的代码(或任何使用模式匹配的等效变体)在我看来是非常错误的。如果它意味着其他东西,那么这种方法可能是正确的(但看起来仍然很奇怪——列表中的字符串是什么?)。标准haskell只支持bug
和rebug
。如果您想要调试,您必须升级到。我甚至要比“从列表索引切换到模式匹配”更进一步:这些字符串应该在记录中传递,每个参数都有描述性名称。是的,但我无法立即找到函数。我假设a1
是if_符号,然后是条件,等等。关于trace
的事情是你需要非常清楚懒惰是如何工作的。例如,尝试(traceM“从不打印”*>pure())()
;在第二个示例中,x
、y
、z
、l
和m
的跟踪几乎保证不会触发,除非解析器
在其(>=)
实现中做了一些非常不寻常的事情,像callseq
或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