Reputation: 35
How come the following
foo :: MonadIO m => m ()
foo = print "hi"
causes the following error
Couldn't match type ‘m’ with ‘IO’ ‘m’ is a rigid type variable bound by the type signature for: foo :: forall (m :: * -> *). MonadIO m => m () at foo.hs:57:8 Expected type: m () Actual type: IO ()
As far as I know, shouldn't the MonadIO constraint allow this to work since IO () should be equal to a MonadIO ?
Upvotes: 2
Views: 252
Reputation: 80744
IO
is not equal to MonadIO
.
MonadIO
is a typeclass that, in plain terms, means that the monad in question can perform IO operations. In practice, since IO
monad is "magic", this can mean only one of two things: the monad in question is IO
itself, or the monad in question wraps IO
in some way.
To express this idea of wrapping, the MonadIO
type class has a method liftIO :: IO a -> m a
, which lets you take an IO
operation and "lift" it (or, if you prefer, "wrap" it) into the monad m
, whatever that is.
So, to fix your code, all you need is liftIO
:
foo :: MonadIO m => m ()
foo = liftIO $ print "hi"
Upvotes: 10