Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Couldn't match type error even with type constraint

Tags:

haskell

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 ?

like image 548
xicohuni Avatar asked Dec 31 '25 01:12

xicohuni


1 Answers

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"
like image 94
Fyodor Soikin Avatar answered Jan 01 '26 17:01

Fyodor Soikin