用monad变压器避免升降 [英] Avoiding lift with monad transformers

查看:166
本文介绍了用monad变压器避免升降的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,在 IO 上有一堆monad变换器(甚至是一个monad变换器)。一切都很好,除了在每个动作之前使用电梯是非常烦人的!我怀疑这确实没有什么可做的,但我想我会问的。



我知道提升整个块,但如果代码真的混合类型?如果GHC引入了一些语法糖(比如< - $ = < - lift

mtl monads,根本不需要 lift 获得放置告诉 - 它们都可以在任何单元中使用正确的变压器在堆栈中的某处。缺少的部分是 IO ,并且甚至 liftIO 会在任意数量的层下提取任意的IO操作。 p>

对于提供的每个效果,这通过类型类来完成:例如, MonadState 提供了 get 放入。如果你想创建你自己的 newtype 包装器,你可以做派生(...,MonadState MyState,...)加上 GeneralizedNewtypeDeriving 扩展名,或者滚动您自己的实例:

  instance MonadState MyState MyMonad其中
get = MyMonad获取
put s = MyMonad(put s)

您可以使用它来选择性地显示或隐藏组合转换器的组件,方法是定义一些实例而不是其他。

通过定义你自己的类型类并为标准变换器提供样板实例,将这种方法扩展到你自己定义的全新单点效果,但是全新的单子很少见;大多数情况下,只需编写标准集由mtl提供。)


I have a problem to which a stack of monad transformers (or even one monad transformer) over IO. Everything is good, except that using lift before every action is terribly annoying! I suspect there is really nothing to do about that, but I thought I'd ask anyway.

I am aware of lifting entire blocks, but what if the code is really of mixed types? Would it not be nice if GHC threw in some syntactic sugar (for example, <-$ = <- lift)?

解决方案

For all the standard mtl monads, you don't need lift at all. get, put, ask, tell — they all work in any monad with the right transformer somewhere in the stack. The missing piece is IO, and even there liftIO lifts an arbitrary IO action down an arbitrary number of layers.

This is done with typeclasses for each "effect" on offer: for example, MonadState provides get and put. If you want to create your own newtype wrapper around a transformer stack, you can do deriving (..., MonadState MyState, ...) with the GeneralizedNewtypeDeriving extension, or roll your own instance:

instance MonadState MyState MyMonad where
  get = MyMonad get
  put s = MyMonad (put s)

You can use this to selectively expose or hide components of your combined transformer, by defining some instances and not others.

(You can easily extend this approach to all-new monadic effects you define yourself, by defining your own typeclass and providing boilerplate instances for the standard transformers, but all-new monads are rare; most of the time, you'll get by simply composing the standard set offered by mtl.)

这篇关于用monad变压器避免升降的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆