Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of liftIO?

Tags:

haskell

I have the following code snippet from internet:

calculateLength :: LengthMonad Int
calculateLength = do
  -- all the IO operations have to be lifted to the IO monad in the monad stack
  liftIO $ putStrLn "Please enter a non-empty string: "
  s <- liftIO getLine
  if null s
    then throwError "The string was empty!"
    else return $ length s

and could not understand, why the author use liftIO?

What is the purpose of liftIO?

It is defined as follows:

class (Monad m) => MonadIO m where
    -- | Lift a computation from the 'IO' monad.
    liftIO :: IO a -> m a  

Is it possible to lift IO a -> [a]? It looks like natural transformation.

like image 511
softshipper Avatar asked Oct 13 '19 18:10

softshipper


1 Answers

IO operations like getLine, putStrLn "..." only work inside the IO monad. Using them inside any other monad will trigger a type error.

Still, there are many monads M which are defined in terms of IO (e.g. StateT Int IO, and apparently your LengthMonad as well) and because of that they allow IO actions to be converted into M-actions, and executed as such.

However, we need a conversion for each M:

convertIOintoM1 :: IO a -> M1 a 
convertIOintoM2 :: IO a -> M2 a
convertIOintoM3 :: IO a -> M3 a
...

Since this is cumbersome, the library defines a typeclass MonadIO having such conversion function, so that all the functions above can be named liftIO instead.

In practice, liftIO is used each time one wants to run IO actions in another monad, provided such monad allows for it.

like image 192
chi Avatar answered Feb 02 '23 12:02

chi