对haskell中“groupBy”的评价
为什么对haskell中“groupBy”的评价,haskell,Haskell,为什么 groupBy (>) [-5,-4,5,4,-2,-3,2,3] 评估 [[-5],[-4],[5,4,-2,-3,2,3]] 由于-3不大于2,它是否应该对它们进行不同的分组? 我原以为结果会很好 [[-5],[-4],[5,4,-2,-3],[2,3]] 我缺少什么?groupBy::(a->a->Bool)->[a]->[[a]]]使用组的第一个成员作为参考。所以如果你写: groupBy eq (x:x2:x3) 它将-如果满足eq x x2,则调用eq x x3
groupBy (>) [-5,-4,5,4,-2,-3,2,3]
评估
[[-5],[-4],[5,4,-2,-3,2,3]]
由于-3
不大于2
,它是否应该对它们进行不同的分组?
我原以为结果会很好
[[-5],[-4],[5,4,-2,-3],[2,3]]
我缺少什么?groupBy::(a->a->Bool)->[a]->[[a]]]
使用组的第一个成员作为参考。所以如果你写:
groupBy eq (x:x2:x3)
它将-如果满足eq x x2
,则调用eq x x3
检查x3
是否也属于同一组。因此,电话是:
arg1 | arg2 | (>) `on` (*1)
-5 | -4 | False
-4 | 5 | False
5 | 4 | True
5 | -2 | True
5 | -3 | True
5 | 2 | True
5 | 3 | True
如您所见,span
将eq x
作为谓词,x
是组中的第一个成员
函数可能期望a->a->Bool
是一个等价关系:等价关系是(1)自反的;(2) 对称的;及物性。你的函数不是等价关系,因为它不是自反的,也不是对称的。因此,您不能(安全地)将groupBy
与订单关系一起使用
注意:`(*1)上的
(>)`on`(*1)
相当于只(>)
,因为(*1)
将返回相同的数字,您只需在此处使函数更具体,只在Num
s上工作,但这不是必需的。否,它总是在组的第一个成员上调用它。因此,它将-3
与5
进行比较。我试图修改您的格式。您应该缩进以格式化较长的代码段。反勾只对非常小的块非常有用。哦!可以感谢您的解释和有关缩进的提示。在比较之前,将每个数字乘以1有什么意义?我在试图了解on
的工作原理时,将其乘以1。为了避免混淆,我编辑了这个问题。我想知道这个行为是由库保证的,还是它的实现中的一个意外事件。文档没有指定eq
是否必须是等价关系。它只是指“平等测试”。(也许应该保守一点,只对eq
)使用等价物@chi:我同意,这可能是一个实现细节。我添加了一个注释,eq
应该是一个等价关系。谢谢你的反馈。
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy _ [] = []
groupBy eq (x:xs) = (x:ys) : groupBy eq zs
where (ys,zs) = span (eq x) xs