如何在函数内部打印变量?

时间:2018-06-28 20:37:05

标签: haskell pattern-matching

我有一个功能:

fold_wrap :: (a -> a -> a) -> (Prop -> a) -> a -> Wrapper -> a

fold_wrap v x z (Mrappe l r)   = v ( v(v x z l) v(v x z r) )
fold_wrap v x z (Wrap f)       = x f 
fold_warp v x z (Wtail )       = z

在遇到以下错误的地方:

mast: mast.hs:(15,1)-(16,31): Non-exhaustive patterns in function fold_mast

所以我添加了

fold_wrap v x z _ = z 

修正了错误,但

这使我相信某些模式确实不匹配。

现在,解决此问题的直觉是打印传递给函数的内容。

所以我添加了这个

fold_wrap  v x z g = print g

但是那都不起作用,因为函数必须返回a类型而不是IO

所以我的问题是:

如何打印g并同时返回一些虚拟值?

还应了解有关如何修复此非穷举模式匹配的提示。

1 个答案:

答案 0 :(得分:5)

我不知道您使用的rake create_dev_team[Team\ Name]的定义,是您的非穷尽模式问题。但是,我可以回答您提出的问题。

通常,在Haskell中,要打印一个值,我们需要在返回类型中使用Wrapper。这使代码功能保持纯净,并为我们带来了很多好处,因此我们切勿尝试在生产代码中违反此规则。

但是,您的脑子里总有那种讨厌的小声音,只想打印一个值用于调试目的。请记住,永远不要在成品中完成此操作;仅出于调试原因。但是,由于这个原因,Haskell提供了一个IO模块,它打破了所有理智和正常的功能规则,让您可以做到这一点。

Debug.Trace

现在,有一些注意事项。首先,import Debug.Trace fold_wrap v x z g = traceShow g someDummyValue 仍然必须具有Wrapper。我们对此无能为力。如果Haskell不知道如何打印某些内容,则即使进行调试也无法打印。其次,Haskell是非严格的,因此在运行代码时,需要确保对Show调用进行了实际评估。仅仅调用它并将结果绑定到一个虚拟变量上是不会的。您实际上需要获取该哑数值,并在绝对需要对其进行评估的某些情况下使用它,通常是通过在fold_wrap中将其打印出来。

我之前说过这个,但是我再说一遍,因为它很重要。 main仅用于调试。它可能会上瘾,尤其是如果您是Haskell的新手。但是请勿在生产代码中使用该模块。它有很多问题,例如不能保证打印顺序,这些问题在调试时无关紧要,而在面向用户的代码中使用时,则很重要。更不用说它破坏了本书中的每一个Haskell规则。