如何根据 Haskell 中的整数列表制作直方图?

How can I make a histogram from a list of integers in Haskell?

我是 Haskell 初学者。从整数列表制作直方图的最简单方法是什么?假设我有一个这样的列表:

l = [1, 2, 3, 5, 7, 7, 7, 10] 

我希望能够 histogram 2 l(2 个垃圾箱)并拥有它 return:

[(0, 3), (1, 5)] 

因为第0(上)半场有3个号码,下半场有5个号码。

似乎有很多库可以执行此操作,但是将整数列表编组到向量或其他数据结构中或从中编组确实让我感到困惑。

这是我尝试过的一件事:

import Statistics.Sample.Histogram

l =  [1, 2, 3, 5, 6, 7, 7, 7, 7] :: [Double]

main = print $ snd $ histogram 10 l

但是它抛出的错误是:

histogram-test.hs:6:8: error:
    • Ambiguous type variables ‘v10’,
                               ‘b0’ arising from a use of ‘print’
      prevents the constraint ‘(Show (v10 b0))’ from being solved.
      Probable fix: use a type annotation to specify what ‘v10’,
                                                          ‘b0’ should be.
      These potential instances exist:
        instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
        instance (Show a, Show b) => Show (a, b) -- Defined in ‘GHC.Show’
        instance (Show a, Show b, Show c) => Show (a, b, c)
          -- Defined in ‘GHC.Show’
        ...plus 13 others
        ...plus 19 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: print $ snd $ histogram 10 l
      In an equation for ‘main’: main = print $ snd $ histogram 10 l
  |
6 | main = print $ snd $ histogram 10 l
  |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

histogram-test.hs:6:22: error:
    • No instance for (Data.Vector.Generic.Base.Vector [] Double)
        arising from a use of ‘histogram’
    • In the second argument of ‘($)’, namely ‘histogram 10 l’
      In the second argument of ‘($)’, namely ‘snd $ histogram 10 l’
      In the expression: print $ snd $ histogram 10 l
  |
6 | main = print $ snd $ histogram 10 l
  |                      ^^^^^^^^^^^^^^
Failed, no modules loaded.

我认为您必须明确说明您希望获得的数据类型。

$ ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/  :? for help
 ... 
 λ> 
 λ> import qualified Data.Vector as V
 λ> import Statistics.Sample.Histogram
 λ> 
 λ> l =  [1, 2, 3, 5, 6, 7, 7, 7, 7] :: [Double]
 λ> hi = (histogram 10 (V.fromList l)) :: (V.Vector Double, V.Vector Int)
 λ> 
 λ> part2 = snd hi
 λ> 
 λ> part2
 [1,1,0,1,0,0,1,1,0,4]
 λ> 

此外,统计人员可能绝大多数都是 Fortran/C/C++ 文化,因此他们认为 Haskell 列表对计算机科学家来说是很好的东西;然而,在进行 统计 时,列表应该被转换成一些重要的数据类型,如序列或向量。

什么错误行:

No instance for (Data.Vector.Generic.Base.Vector [] Double)

的意思是告诉我们一个list不能做一个合适的vector,那是function的合适食物histogram。您必须明确允许编译器将列表转换为向量。

无需依赖任何库(容器除外,为结果提供 Map 类型)即可轻松实现此功能:

frequencies :: Ord a => [a] -> M.Map a Int
frequencies = foldr (\x m -> M.insertWith (+) x 1 m) M.empty