Haskell是否支持调试?



例如,这是一个函数:

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

我需要看看每个指令真正做什么

您可以使用Debug.Tracetrace :: String -> a -> a,或相关函数,如traceShowId :: Show a => a -> a。此函数基本上在函数被计算时打印附加的String参数,并返回函数的结果。

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

除了你的函数,我建议在这里使用模式匹配,并消除未使用变量的噪音:

iffthen :: [String] -> Parser String
iffthen(ifs : cond : thens : val1 : elses : val2 : _)= do 
symbolifs
booleanacond
symbolthens
k <- assignPval1
symbolelses
assignPval2
return k

(鉴于我相应地解释了您想要的内容,并且ifsthenselses是符号,cond是条件,val1val2if-then-else表达式的值(。

最好不要使用列表(因为在编译时不能保证元素的数量(,从而使用特定参数构造一个 sperate 类型。

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

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

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

如果您对每个解析器的结果感兴趣,请将traceShowId<$>等一起使用。

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

ghci确实有一个步进调试器。由于Haskell代码往往是功能性和懒惰的,我认为它有时会导致惊喜。Emacshaskell-mode曾经有调试器集成...我想我遇到了该集成作者的评论,指出调试器在某些方面有问题,但现在找不到它。但是我已经在一些基本示例中尝试了调试器,它的工作原理如广告所示。

最新更新