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

有帮助吗?

解决方案

lift 总是从“上一个”层抬起。如果您需要从第二层提起,则需要 lift . lift 等等。

另一方面, liftIO 总是从IO层抬起(在场时,始终在堆栈的底部)。因此,如果您有超过2层的单子,您将不胜感激 liftIO.

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

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

其他提示

Liftio只是IO MONAD的捷径,无论您所在的单一单元,Liftio等于使用可变数量的升降机。首先,这听起来可能是多余的,但是使用Liftio具有一个很大的优势:它使您的IO代码属于实际的单调结构,因此您可以重复使用相同的代码,无论您的最终单子构建的层数是多少(这很重要,编写单调变压器时)。

在ohter的手上,Liftio并非像Lift一样免费出现:您使用的单子变压器必须对其进行支持,例如,您所使用的单调必须是Monadio类的一个实例,但是如今大多数Monads都这样做(当然,类型检查器将在编译时间为您检查一下:这就是Haskell的优势!)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top