Ten*_*ner 15 monads haskell monad-transformers
我发现monad变换器的一个问题是需要lift将操作转换为正确的monad.单lift在这里和那里也不错,但有时也有功能类似如下:
fun = do
lift a
lift b
c
lift d
lift e
f
Run Code Online (Sandbox Code Playgroud)
我希望能够这样编写这个函数:
fun = monadInvert $ do
a
b
lift c
d
e
lift f
Run Code Online (Sandbox Code Playgroud)
这会减少lifts 的数量并使代码更清晰.
问题是:对于monads是monadInvert可能的?应该如何创建这个功能?
加分点:定义它monad m的实例MonadIO.
这个问题的标题提到了排列:实际上,我们如何处理monad变换器堆栈的任意排列?
小智 16
嗯,首先,你实际上并不需要这么多提升.对于monad变换器,以下标识包含:
lift c >>= lift . f = lift (c >>= f)
lift c1 >> lift c2 = lift (c1 >> c2)
Run Code Online (Sandbox Code Playgroud)
写作并不罕见:
x <- lift $ do
{- ... -}
Run Code Online (Sandbox Code Playgroud)
接下来是:当您使用mtl或monadLib等库(即基于类型类的库而不是直接使用变换器)时,您实际上可以直接访问大多数底层monad:
c :: StateT MyState (ReaderT MyConfig SomeOtherMonad) Result
c = do
x <- ask
y <- get
{- ... -}
Run Code Online (Sandbox Code Playgroud)
最后,如果你真的需要大量提升尽管有这两点,你应该考虑编写一个自定义monad甚至使用完全不同的抽象.我发现自己使用自动机箭头进行有状态计算而不是状态monad.
Nic*_* Wu 10
你可能感兴趣于Monads,Zippers和Views,虚拟化Monad Stack by Tom Schrijvers和Bruno Oliveira.
这并没有解决你关于减少升降机的问题,但这对你的"monad排列"问题来说是一个有趣的方法.
这是摘要:
这项工作旨在通过采用两种新技术来虚拟化monad堆栈:monad拉链和monad视图,使monadic组件更具可重用性和更强大的变化.monad拉链是monad变换器,通过忽略具体堆栈中的特定层来创建虚拟monad堆栈.Monad视图为monad堆栈虚拟化提供了一个通用框架:它们将monad zipper更进一步,并将其与各种其他虚拟化集成.例如,特定视图允许对堆栈中的monad进行受限访问.此外,组件可以使用monad视图来提供类似于引用的调用机制来访问monad堆栈的特定层.通过这两种机制,就monad堆栈形状而言,组件需求不再需要在具体的monad堆栈中逐字反映,从而使这些组件更易于重复使用并且对变化具有鲁棒性.
| 归档时间: |
|
| 查看次数: |
459 次 |
| 最近记录: |