Haskell 有没有一种方法可以在不重叠实例的情况下,使用monad类型变量以多态方式提升类的实例?
这一问题可以被视为是一个后续问题 它提供了一个应用程序示例,说明了将在何处使用它 这个想法是一个typeclassHaskell 有没有一种方法可以在不重叠实例的情况下,使用monad类型变量以多态方式提升类的实例?,haskell,typeclass,monad-transformers,overlapping-instances,Haskell,Typeclass,Monad Transformers,Overlapping Instances,这一问题可以被视为是一个后续问题 它提供了一个应用程序示例,说明了将在何处使用它 这个想法是一个typeclass 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 。我想要的是一
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替换。提升
建议使用类似的默认实例
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(tm)A
实例(MonadTrans t)=>Class(t(tm))B
这是可行的,但需要为每个基础实例声明提升实例[…]
这并不是那些默认设置的用途。实例应该如下所示
instance Class m a => Class (StateT s m) a
instance Class m a => Class (MaybeT m) a
等等。你写
instance(MonadTrans t)=>Class(tm)A
实例(MonadTrans t)=>Class(t(tm))B
这是可行的,但需要为每个基础实例声明提升实例[…]
这并不是那些默认设置的用途。实例应该如下所示
instance Class m a => Class (StateT s m) a
instance Class m a => Class (MaybeT m) a
等等。为什么您首先需要一个
类(tm)B
实例?难道这种情况不能被(MonadTrans t,Class ma)=>Class(tm)a
所涵盖吗?或者将tm
限制为仅B
,但不允许a
与tm
一起使用的想法是B
的方法的实现在tm
中,而且不可能仅在M
@notBob中定义。我们是否可以假设基本实例集是“封闭的”,即库的用户无法扩展?@danidiaz不,这是无法假设的。虽然我可能是它的唯一用户,但我打算在本模块中只保留最一般的内容,并在其他模块中定义实例。为什么您首先需要Class(tm)B
实例?难道这种情况不能被(MonadTrans t,Class ma)=>Class(tm)a
所涵盖吗?或者将tm
限制为仅B
,但不允许a
与tm
一起使用的想法是B
的方法的实现在tm
中,而且不可能仅在M
@notBob中定义。我们是否可以假设基本实例集是“封闭的”,即库的用户无法扩展?@danidiaz不,这是无法假设的。虽然我可能是它的唯一用户,但我打算在这个模块中只保留最一般的内容,并在其他模块中定义实例。