Haskell相当于Scala的groupBy

Imp*_*ive 20 haskell scala

Scala groupBy在列表上有一个函数,它接受从列表项中提取键的函数,并返回另一个列表,其中的项是由键和生成该键的项列表组成的元组.换句话说,这样的事情:

List(1,2,3,4,5,6,7,8,9).groupBy(_ % 2)
// List((0, List(2,4,6,8)), (1, List(1,3,5,7,9)))
Run Code Online (Sandbox Code Playgroud)

(实际上,它看起来像在当前版本中提供了一个Map,但这并不重要).C#有一个更有用的版本,可以让你同时映射值(如果你的关键函数只是提取元组的一部分,那么非常有用).

Haskell有一个groupBy,但它有点不同 - 它根据一些比较函数对事物进行分组.

在我去写它之前,groupBy在Haskell中是否有相当于Scala的东西?Hoogle对于我希望签名看起来像什么(下图)没有任何东西,但我可能错了.

Eq b => (a -> b) -> [a] -> [(b,[a])]
Run Code Online (Sandbox Code Playgroud)

Nik*_* B. 17

您可以自己编写函数,但是如果需要有效的解决方案,则需要对分类器函数的结果进行约束OrdHashable约束.例:

import Control.Arrow ((&&&))
import Data.List
import Data.Function

myGroupBy :: (Ord b) => (a -> b) -> [a] -> [(b, [a])]
myGroupBy f = map (f . head &&& id)
                   . groupBy ((==) `on` f)
                   . sortBy (compare `on` f)

> myGroupBy (`mod` 2) [1..9]
[(0,[2,4,6,8]),(1,[1,3,5,7,9])]      
Run Code Online (Sandbox Code Playgroud)

您也可以使用哈希映射,Data.HashMap.Strict而不是排序预期的线性时间.