Reputation: 5658
I try to work with the Reader Monad
m = Map.fromList [("a","b"), ("b","c"), ("c","d"), ("d","e")]
f x m = fromMaybe "default value" $ Map.lookup x m
lookup' x = f x m
Now I wanted to create a reader monad:
r = reader lookup'
-- Non type variable argument:
-- in the constraint MonadReader [Char] m
-- When checking the inferred type:
-- b :: forall (m :: * -> *). MonadReader [Char] m => m [Char]
The solution was to define the type:
r = reader lookup' :: Reader String String
Why does this solve the problem?
Upvotes: 2
Views: 137
Reputation: 32319
The immediate problem is due to the monomorphism restriction. The hand-waving explanation for this case is that r = reader lookup'
looks like you are defining some concrete r
, so Haskell will try to infer a monomorphic type signature for it (one without type variables).
Since you imported reader :: MonadReader r m => (r -> a) -> m a
, the Haskell infers that reader lookup' :: MonadReader [Char] m => m [Char]
. Unfortunately, this is not monomorphic - Haskell doesn't know exactly what you want m
to be. That is what the error message is saying: the type variable m
is ambiguous.
Adding an explicit type annotation like reader lookup' :: Reader String String
removes this problem; it is now possible to infer that m ~ Reader String
.
Upvotes: 3