有没有一种方法可以将带有monad类型变量的类的实例多态提升,而又不会重叠实例?

问题描述

这个问题可以被视为

的后续活动

Lift instance of class with a `MonadIO` type-variable to the transformed monad

其中提供了将在何处使用的示例应用程序。

这个想法是一个类型类

class (Monad m) => Class m a where
  method :: a -> m ()

存在,并且基本实例位于不同的monad中

instance Class M A where 
  method = undefined

instance Class (T M) B where
  method = undefined

。我想要的是一种将任何实例提升到自身或在变压器堆栈中更高的方式,就像liftIOIO所做的那样。我最初的想法是定义一个提升实例

instance (MonadTrans t,Class m a) => Class (t m) a where
  method = lift . method 

但是,这存在一个问题,即当应用多个变压器时,会创建重叠的实例,因为lift是多态的,并且可以用lift . lift代替。

建议改用类似的认实例

class (Monad m) => Class m a where
  method :: a -> m ()
  default method :: (m ~ t n,MonadTrans t,Class n a) => a -> m ()
  method = lift . method

然后可以用来声明提升实例

instance (MonadTrans t) => Class (t M) A

instance (MonadTrans t) => Class (t (T M)) B

。这可行,但是需要为每个基本实例声明提升实例,所以我很好奇。还有其他方法可以解决此问题而无需求助于重叠的实例吗?

解决方法

您写

instance (MonadTrans t) => Class (t M) A
instance (MonadTrans t) => Class (t (T M)) B

这可行,但是需要为每个基本实例声明提升实例[....]

这不是打算使用这些默认值的方式。实例看起来应该像

instance Class m a => Class (StateT s m) a
instance Class m a => Class (MaybeT m) a

以此类推。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...