Haskell:Lift vs Liftio
-
29-09-2019 - |
题
在什么情况下 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的优势!)。
不隶属于 StackOverflow