这个问题可以认为是后续问题
将具有“MonadIO”类型变量的类实例提升到转换后的 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
. 我想要的是一种将任何实例提升到自身或在变压器堆栈中更高的方法,就像liftIO
为IO
. 我最初的想法是定义一个提升实例
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
. 这可行,但是需要为每个基本实例声明提升实例,所以我很好奇;有没有其他方法可以在不使用重叠实例的情况下解决这个问题?