首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Haskell为Monad-Transformers实现lift型电梯

在Haskell为Monad-Transformers实现lift型电梯
EN

Stack Overflow用户
提问于 2021-10-11 22:13:00
回答 1查看 155关注 0票数 1

我目前正在Haskell学习使用Monad-Transformers。我使用StateTExceptT组成了一个简单的单台转换器。

代码语言:javascript
复制
type DatabaseT m = StateT DatabaseState (ExceptT DatabaseError m)

已经有一些与DatabaseT一起工作的函数,如:

代码语言:javascript
复制
connectDB :: MonadIO m => DBMode -> DatabaseT m ()
isConnected :: Monad m => DatabaseT m Bool

为了使这些函数的提升更容易,我想定义一个类似于MonadIO的类型类。

代码语言:javascript
复制
class Monad m => MonadDB m where
  liftDB :: Monad m' => DatabaseT m' a -> m a

现在,有问题的部分是将DatabaseT m作为一个实例(如果是MonadDB )。查看implementation of MonadIO,这个函数应该是标识函数:

代码语言:javascript
复制
instance Monad m => MonadDB (DatabaseT m) where
  liftDB = id

但是,这段代码没有编译:

代码语言:javascript
复制
Couldn't match type ‘m'’ with ‘m’
  ‘m'’ is a rigid type variable bound by
    the type signature for:
      liftDB :: forall (m' :: * -> *) a.
                Monad m' =>
                DatabaseT m' a -> DatabaseT m a
  ‘m’ is a rigid type variable bound by
    the instance declaration
  Expected type: DatabaseT m' a -> DatabaseT m a
    Actual type: DatabaseT m a -> DatabaseT m a
In the expression: id
  In an equation for ‘liftDB’: liftDB = id
  In the instance declaration for ‘MonadDB (DatabaseT m)’
Relevant bindings include
    liftDB :: DatabaseT m' a -> DatabaseT m a

似乎有一个Monad MyMonad的Monad变压器类型类,具有类似于liftMyMonad的函数,当MyMonad本身是Monad-转换器时,它就不能工作了。

这是一种使DatabaseT m操作的提升更通用的有效方法,还是根本上存在缺陷?

如果是这样的话,我如何从DatabaseT m堆栈的任何位置提升DatabaseT操作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-11 22:38:35

你想要的结束状态可能不是你想要的结束状态。也就是说,对于大多数需求来说,这并不是很好:

代码语言:javascript
复制
class Monad m => MonadDB m where
  liftDB :: Monad m' => DatabaseT m' a -> m a

典型的解决方案是根本不编写这样的实例,而是编写:

代码语言:javascript
复制
class Monad m => MonadDB m where
  connectDB :: DBMode -> m ()
  isConnected :: m Bool

这使你能够:

  • 在一元上下文中使用函数,其中DatabaseT是一个组件,
  • 使用MonadMock这样的解决方案来测试
  • ,而不是破坏抽象--完全避免在消费者代码中使用lift
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69532999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档