Haskell: лифт против лифта - PullRequest
       2

Haskell: лифт против лифта

74 голосов
/ 13 октября 2010

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

Ответы [ 2 ]

84 голосов
/ 13 октября 2010

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
31 голосов
/ 13 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...