Tre*_*edJ 2 haskell hashmap type-constraints
我有这个工作函数,它计算列表中每个元素的出现次数并从中构建一个映射:
import qualified Data.HashMap.Strict as M
counter :: [Int] -> M.HashMap Int Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty
Run Code Online (Sandbox Code Playgroud)
现在我想将其概括为:
counter :: (Eq k) => [k] -> M.HashMap k Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty
Run Code Online (Sandbox Code Playgroud)
但显然,我也需要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
Run Code Online (Sandbox Code Playgroud)
1: 添加hashable-1.3.1.0:Data.Hashable.Class.Hashable k
(如错误所建议的), Data.Hashable.Class.Hashable k
, 或M.Hashable k
到类型约束不起作用。导入 Data.Hashable.Class 不起作用,因为它是一个隐藏的模块。
你从Data.Hashable
模块导入它,所以:
import Data.Hashable(Hashable)
counter :: (Hashable k, Eq k) => [k] -> M.HashMap k Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty
Run Code Online (Sandbox Code Playgroud)
您目前可能没有公开该hashable
包,在您的 .cabal 文件中,您可以在依赖项下列出它:
-- …
executable …
-- …
build-depends:
base >= 4.7 && < 5
, hashable >=1.0
-- …
-- …
Run Code Online (Sandbox Code Playgroud)