发布于 2010-11-25 10:37:15
我认为每个人的建议是把事情分解成更容易处理的部分,这是最好的方法。调试较小表达式的一个技巧是窃取Ruby的tap函数,如here所述。"tap“允许你像这样把一个表达式放在链的中间,也许还可以打印出一些调试值,如下所示:
val ls = List(1,2,3).map(_ * 2)
.tap(soFar => println("So far: " + soFar))
.map(_ * 2)
println(ls)
这将打印出来:
到目前为止的列表:
(2,4,6)
列表(4,8,12)
它每隔一段时间就对我有帮助。
发布于 2010-11-25 12:37:10
在纯粹的函数式设置中,单步执行并不像您想象的那样有用。因为所有东西都是由纯函数组成的,所以您可以使用消除过程来单独测试这些部分。在懒惰的计算环境中,单步执行代码的用处更小。
例如,在Haskell中调试程序,您根本不会对跟踪函数调用感兴趣。您感兴趣的是中间函数返回值的跟踪。在任何函数式语言中,能够为任何表达式提供这样的跟踪将是一个非常有用的功能。
发布于 2010-11-25 09:31:28
我知道简洁是非常好的,我同意您的观点,IDE应该有助于在这些情况下进行调试。但就目前而言,我已经改变了我的编码风格,以帮助调试。以我个人的风格,我会把你的例子实现为:
val noZeroLs = ls.filter(_>1)
val sortedLs = noZeroLs.sort(_<_)
val indexedNoZeroLs = sortedLs.zipWithIndex
val everySecondIndexedL = indexedNoZeroLs.filter(v => (v._2) % 2 == 0)
val everySecondL = everySecondIndexedL.map(_._1)
想出有意义的名称是困难的/费力的,但它确实可以帮助您识别愚蠢的but;可能有助于其他人理解正在发生的事情;并且肯定有助于调试。
https://stackoverflow.com/questions/4272797
复制相似问题