假设我有简单的新类型声明
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
我想创建 MonadBaseControl IO 的 Foo 实例。这应该很容易,因为 ReaderT Int IO 已经是 MonadBaseControl IO 的实例。但是,使用 GeneralizedNewtypeDeriving 自动派生它不起作用,因为 MonadBaseControl 类具有关联的类型。
如何为 Foo 编写 MonadBaseControl IO 实例? defaultLiftBaseWith 和 defaultRestoreM 应该会有帮助,但破译它们的类型有点困难。
Foo
既不是“基础”单子,也不是单子转换器。defaultLiftBaseWith
在这里没有帮助,因为你想要实例Foo
与 相同ReaderT Int IO
.
首先,使用 GND 获取无聊实例:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Trans.Control
import Control.Monad.Base
import Control.Monad.Reader
import Control.Applicative
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO)
实例为MonadBaseControl IO
只是删除新类型,使用来自ReaderT
实例,并将结果放回新类型中:
instance MonadBaseControl IO Foo where
type StM Foo a = a
liftBaseWith f = Foo $ liftBaseWith $ \q -> f (q . unFoo)
restoreM = Foo . restoreM
请注意,如果StM
wasn't关联类型系列,你可以做类似的事情
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO, MonadBaseControl IO)
type instance StM Foo a = a
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)