I just tried to use writer
:
writer (5, "Hello, World")
But I noticed I get an error:
Non type-variable argument in the constraint
MonadWriter [Char] m
But I wonder what constraint I don't fulfill? [a]
after all is a Monoid...
It’s just a check to keep type checking “simple”
writer (5, "Hello world") :: (MonadWriter String m, Num n) => m n
which is a perfectly sensible type. However, by default, it is not allowed, because the constraint MonadWriter String m
contains a type argument String
, which isn’t a variable. This was done with the intent that it would stop the delaying of type errors:
class C c where c :: c -> c
-- no instance C Int
x :: C Int => Int
x = c (5 :: Int)
-- illegal with above restriction
-- missing instance error (maybe) delayed to user without
Simply set -XFlexibleContexts
to disable the check.
As for other monads, I’m pretty sure Reader
, State
, and Free
will do this too.
{-# LANGUAGE ... #-}
pragma. – David YoungrunWriter
). – leftaroundaboutwriter (5,"foo") :: Writer String Char
works. But why this behavior? All the other monads inControl.Monad.
don't have this behavior... – hgieselFlexibleContexts
,MonadWriter [Char] m
simply isn't a valid type (but it is the constraint of the inferred type of the given expression, so the given expression is not type correct). The same thing happens with other monad transformers (e.g.put "x"
or('a':) <$> ask
) – user2407038