Haskell:Lift vs LiftIO


82

在什么情况下应该 liftIO使用?当我使用时ErrorT String IO,该lift功能可以将IO操作提升为ErrorT,因此liftIO似乎是多余的。

Answers:


93

lift总是从“上一个”层抬起。如果您需要从第二层抬起,则需要lift . lift依此类推。

另一方面,liftIO总是从IO层提升(当存在时,IO层始终位于堆栈的底部)。因此,如果您拥有2层以上的monad,您将不胜感激liftIO

比较以下lambda中的参数类型:

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

33
liftIO即使lift足够,我通常也会使用IO层,因为这样我就可以更改monad堆栈,并且代码仍然有效。
约翰L

14
@约翰:好点。而且很明显,您正在提升IO,而不是其他任何monad。
罗曼·切普利卡

我是新手:lift假设此答案(和问题)来自Control.Monad.Trans.Class,我猜呢?不是 Monadic lifting或者在第一部分中描述的一般吊装在这里
纳瓦兹

37

liftIO只是IO Monad的快捷方式,无论您位于哪个Monad。基本上,liftIO等于使用可变数量的提升。最初,这听起来可能是多余的,但是使用liftIO有一个很大的优势:它使您的IO代码独立于实际的Monad构建,因此无论您构建最终Monad的层数如何,您都可以重用相同的代码(这很重要编写monad变压器时)。

另一方面,liftIO并不是免费提供的,就像lift一样免费:您使用的Monad变压器必须对此提供支持,例如,您所使用的Monad必须是MonadIO类的实例,但如今大多数Monad都这样做(当然,类型检查器会在编译时为您检查:这就是Haskell的优势!)。


1

先前的答案都很好地解释了差异。我只是想对内部工作方式有所了解,以便可以更容易地理解liftIO它不是什么神奇的东西(对于像我这样的Haskellers新手来说)。

liftIO :: IO a -> m a

是一个明智的工具

lift :: (Control.Monad.Trans.Class.MonadTrans t, Monad m) => m a -> t m a

最经常当底部单子是使用IO。对于IOmonad,其定义非常简单。

class (Monad m) => MonadIO m where
  liftIO :: IO a -> m a

instance MonadIO IO where
  liftIO = id

这个简单的...liftIO实际上仅id适用于IOmonad,基本上IO是类型类定义中唯一的一个。

问题是,当我们有一个monad类型,它由over上的多层monad变压器组成时IO,最好MonadIO为每个monad变压器层都有一个实例。例如,MonadIO实例MaybeT m需要m是的MonadIO requiretypeclass。

编写MonadIO实例基本上也是一个非常简单的任务。因为MaybeT m它的定义像

instance (MonadIO m) => MonadIO (MaybeT m) where
  liftIO = lift . liftIO

StateT s m

instance (MonadIO m) => MonadIO (StateT s m) where
  liftIO = lift . liftIO

他们都是一样的。当你有一个4层堆栈变压器,那么你要么需要做的想象lift . lift . lift . lift $ myIOAction,或只是liftIO myIOAction。如果你想想看,每次lift . liftIO会带你下一层堆栈中,直到它挖一路下跌到IO在这里liftIO被定义为id和与定型等构成相同的代码liftS的上方。

因此,这基本上就是为什么不考虑变压器堆栈配置的情况,只要所有底层都是其中的成员MonadIO并且MonadTrans一个liftIO就可以了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.