nubBy没有按预期工作

时间:2015-11-04 20:55:45

标签: haskell

下面的函数应生成素数,但不适用于GHC 7.10.2。还有其他人看到这个吗?

GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> import Data.List
Prelude Data.List> print . take 100 . nubBy (\x y -> x `rem` y == 0) $ [2..]
[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101]

奇怪的是,它似乎在这个网站上运行良好:

rextester.com/LWZCQ71376

2 个答案:

答案 0 :(得分:14)

base-4.7.x和base-4.8.0.0之间的变化是elem_by的定义,nubBy是根据elem_by定义的。

在base-4.7 elem_by eq y (x:xs) = y `eq` x || elem_by eq y xs 中有这个子句:

elem_by eq y (x:xs)     =  x `eq` y || elem_by eq y xs

并在base-4.8中将其更改为:

nubBy

这些变化的历史记录在这些TRAC问题中:

请注意,nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs) 的Haskell报告序言版本为:

{{1}}

与base-4.7实现不一致,因此也解释了这一变化。

答案 1 :(得分:3)

在新的基础中,参数的顺序似乎被翻转了。编辑:我称这是一个错误,但另一个答案指出旧的行为是错误的顺序。

您可以通过观察以下内容来查看订单:

> print . take 5 . nubBy (\x y -> trace (show (x,y)) $ x `rem` y == 0) $ [2..]
[2(2,3)
,3(3,4)
(2,4)
,4(4,5)
(3,5)
(2,5)

当然rem 2 4不等于零(等于2),因此它会产生4

请注意,当你在lambda中翻转参数顺序时,你得到了你想要的结果:

> print . take 5 . nubBy (\x y -> trace (show (x,y)) $ y `rem` x == 0) $ [2..]
[2(2,3)
,3(3,4)
(2,4)
(3,5)
(2,5)
....

编辑:由于讨论表明关系应该是相等的并且不管顺序如何操作(我现在都懒得看报告)注意你可以先比较参数并获得稳定的行为方式:

print . take 100 . nubBy (\x y -> rem (max x y) (min x y) == 0) $ [2..]