如何添加 Data.HashMap Hashable 类型约束?

How to add the Data.HashMap Hashable type constraint?

我有这个工作函数可以计算列表中每个元素的出现次数并从中构建映射:

import qualified Data.HashMap.Strict as M

counter :: [Int] -> M.HashMap Int Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty

现在我想概括为:

counter :: (Eq k) => [k] -> M.HashMap k Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty

但显然,我还需要 Hashable k 类型约束,因为 M.insertWith 需要它。我尝试了多种添加约束的方法,但在所有尝试中都惨遭失败1.

是否有一种奇特的方法来添加类型约束或可能对我有帮助的语言编译指示?


完整的错误信息:

    • Could not deduce (hashable-1.3.1.0:Data.Hashable.Class.Hashable
                          k)
        arising from a use of ‘M.insertWith’
      from the context: Eq k
        bound by the type signature for:
                   counter :: forall k. Eq k => [k] -> M.HashMap k Int
        at <interactive>:5:1-43
      Possible fix:
        add (hashable-1.3.1.0:Data.Hashable.Class.Hashable
               k) to the context of
          the type signature for:
            counter :: forall k. Eq k => [k] -> M.HashMap k Int
    • In the expression: M.insertWith (+) x 1
      In the first argument of ‘foldr’, namely
        ‘(\ x -> M.insertWith (+) x 1)’
      In the expression: foldr (\ x -> M.insertWith (+) x 1) mempty

1:向类型约束添加 hashable-1.3.1.0:Data.Hashable.Class.Hashable k(如错误所建议)、Data.Hashable.Class.Hashable kM.Hashable k 不起作用。导入 Data.Hashable.Class 不起作用,因为它是一个隐藏模块。

您从 Data.Hashable 模块导入它,所以:

import Data.Hashable(<strong>Hashable</strong>)

counter :: (<strong>Hashable</strong> k, Eq k) => [k] -> M.HashMap k Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty

您目前可能没有公开 hashable 包,在您的 .cabal 文件中,您可以在依赖项下列出它:

-- …
executable …
  -- …
  build-depends:
      base >= 4.7 && < 5
    , <strong>hashable >=1.0</strong>
    -- …
  -- …