hgiesel
hgiesel

Reputation: 5658

Haskell non type variable argument

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

Answers (1)

Alec
Alec

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

Related Questions