All statements in a block domust have the same type (well, they must have the same monad in their type). In your case, this is InputT IO something(with a monad InputT IO).
getInputLine "$ "has a type InputT IO (Maybe String), so the part is fine.
case, , . - return (), InputT IO (). .
process $ words input. IO (), InputT IO (), .
: , ( "" ) IO x InputT IO x, liftIO:
Just input -> liftIO (process $ words input)
liftIO :: IO a -> InputT IO a ( , : liftIO :: (MonadIO m) => IO a -> m a, ).