【发布时间】:2015-10-26 20:55:35
【问题描述】:
我有这样的代码:
appd (a:e) ((c,b):bs) | a == c && bs /= [] = b:appd(a:e) bs
| a /= c && bs /= [] = appd (a:e) bs
| a /= c && bs == [] = appd e ((c,b):bs)
| otherwise = b:appd e ((c,b):bs)
它遍历两个列表,如[1,2,3] 和[(1,2),(6,5),(3,5)],并获取第一个列表的第一个元素并将其与另一个列表中每个元组的第一个元素进行比较,如果它们相等,则保存该元组的第二个元素。它工作正常,但如果我取第一个列表的第二个元素,则比较不起作用,在本例中为2。
例如,如果我有 [1,2,3] 和 [(1,2),(6,5),(3,5)] 之类的列表,则函数从第一个列表中获取 1 并与 1 进行比较,然后与 6 进行比较,然后与 3 进行比较。不采用第一个列表的第二个元素 - 2 并且不会再次进行比较。怎么了?
【问题讨论】:
-
无法重现:在我的测试中,它确实返回了与
1、2和3配对的结果;例如,appd [1,2,3] [(1,2),(6,5),(3,5)]似乎在崩溃之前正确返回了来自(1,2)的2和来自(3,5)的5。如果我在最后添加(2,4),它会在崩溃之前返回4。然而,这个函数是非常不完整的——它最终在几乎每个输入上都会崩溃。也许如果你解决了这个问题(尝试检查 GHC 的输出并启用-fwarn-incomplete-patterns),它的行为会更像你想要的那样。 -
回答您问题的方法是获取您已隔离的测试用例 (
appd [1,2,3] [(1,2),(6,5),(3,5)]),并在您的头脑中、纸上或使用调试器仔细跟踪它的执行情况,然后思考很难。 -
我试过了,但看不到错误
-
“保存这个元组的第二个元素”是什么意思?这里的“节省”是什么意思?保存是否意味着输出列表将包含该项目?对于
[1,2,3]和[(1,2),(6,5),(3,5)],appd是否应该返回[1,3]?输入列表是否必须具有相同的长度?元组的第二个元素是否曾经使用过? -
它从第一个列表中获取数字 1,并将每个元组的第一个元素与第二个列表进行比较,它比较 1 到 1、1 到 6、1 到 3,如果比较为真,则添加到结果元组的第二个元素,在这种情况下它将是 1。然后它从第一个列表中获取下一个元素并再次执行 copmarison - 2 到 1、2 到 6、2 到 3 .....