我正在尝试做一些可能不可能的事情。我有一个类型是MonadIO
. 如果您在这种类型是某些转换器堆栈的基本单子的上下文中liftIO
执行IO
操作,它将正常工作。所以,我希望能够做的是取一个已经被部分提升(对我的类型)的值,并在一步中提升它的“其余部分”。
我可以通过两种方式做到这一点。一个是我的类型实际上可以很容易地重新嵌入到普通 IO 中,所以我可以这样做:
liftMore :: (MonadIO m) => MyType a -> m a
liftMore x = liftIO $ embedMyTypeInIO x
这有效。IO
但是,如果在仅是基本 monad的上下文中使用,这也提供了一种完全脱离我的类型的方法,这是不可取的。
我也可以通过构建一个MonadIO
使用我的类型作为基础的新类型类来做到这一点,但是它需要为所有东西实例化,这是非常不可取的。我尝试使用 newtype 包装器使每个 monad 转换器成为此类的实例,但无法完全理解。
关于我可以尝试实现此目标的策略的任何想法?(我愿意使用语言扩展,但当然更可取的是 Haskell98 的解决方案)。