Вопрос

В каких ситуациях следует liftIO использоваться? Когда я использую ErrorT String IO, то lift Функция работает, чтобы поднять действия IO в ErrorT, так liftIO кажется лишним.

Это было полезно?

Решение

lift Всегда поднимается из «предыдущего» слоя. Если вам нужно поднять со второго слоя, вам понадобится lift . lift и так далее.

С другой стороны, liftIO Всегда поднимается из слоя IO (который, когда присутствует, всегда находится в нижней части стека). Итак, если у вас есть более 2 слоев монадских, вы будете признателен liftIO.

Сравните тип аргумента в следующих лямбдах:

type T = ReaderT Int (WriterT String IO) Bool

> :t \x -> (lift x :: T)
\x -> (lift x :: T) :: WriterT String IO Bool -> T

> :t \x -> (liftIO x :: T)
\x -> (liftIO x :: T) :: IO Bool -> T

Другие советы

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

На Hand Hand Lifeio не подходит бесплатно, так как подъемник делает: монадские трансформеры, которые вы используете, должен иметь поддержку для него, например, монаду, который вы находитесь, должны быть экземпляром класса Monadio, но большинство монадских (и, конечно, тип проверки типа проверит это для вас в совокупность: это сила Haskell!).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top