Reputation: 9007
I've got this working function that counts the occurrences of each element in a list and constructs a map out of it:
import qualified Data.HashMap.Strict as M
counter :: [Int] -> M.HashMap Int Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty
Now I want to generalise this to:
counter :: (Eq k) => [k] -> M.HashMap k Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty
but apparently, I also need the Hashable k
type constraint since M.insertWith
requires it. I've tried multiple ways of adding the constraint but failed miserably in all attempts1.
Is there a fancy way to add the type constraint or perhaps a language pragma that might help me out?
Full error message:
• 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: Adding hashable-1.3.1.0:Data.Hashable.Class.Hashable k
(as suggested by the error), Data.Hashable.Class.Hashable k
, or M.Hashable k
to the type constraint doesn't work. Importing Data.Hashable.Class doesn't work since it's a hidden module.
Upvotes: 1
Views: 366
Reputation: 477265
You import it from the Data.Hashable
module, so:
import Data.Hashable(Hashable)
counter :: (Hashable k, Eq k) => [k] -> M.HashMap k Int
counter = foldr (\x -> M.insertWith (+) x 1) mempty
You likely do not expose the hashable
package at the moment, in your .cabal file you can list this under the dependencies:
-- …
executable …
-- …
build-depends:
base >= 4.7 && < 5
, hashable >=1.0
-- …
-- …
Upvotes: 7