liftIO - это просто ярлык для монады ввода-вывода, в какой бы монаде вы не находились. По сути, liftIO равняется использованию переменного числа лифтов.Поначалу это может показаться излишним, но использование liftIO имеет одно большое преимущество: он делает ваш IO-код независимым от фактической конструкции Monad, поэтому вы можете повторно использовать один и тот же код, независимо от количества слоев, из которых была построена ваша финальная Monad (это очень важнопри написании монадного трансформатора).
С другой стороны, liftIO не приходит бесплатно, как делает лифт: используемые вами трансформаторы монады должны иметь поддержку, например монада, в которой вы должныбыть экземпляром класса MonadIO, но большинство монад в настоящее время делают это (и, конечно, средство проверки типов проверит это во время компиляции: в этом сила Haskell!).