为新类型创建 MonadBaseControl 实例
creating MonadBaseControl instance for newtype
假设我有简单的新类型声明
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
我想创建 MonadBaseControl IO 的 Foo 实例。这应该很容易,因为 ReaderT Int IO 已经是 MonadBaseControl IO 的一个实例。但是,使用 GeneralizedNewtypeDeriving 自动派生它不起作用,因为 MonadBaseControl class 具有关联类型。
如何为 Foo 编写 MonadBaseControl IO 实例? defaultLiftBaseWith 和 defaultRestoreM 应该会有帮助,但要破译它们的类型有点困难。
Foo
既不是 "base" monad,也不是 monad 转换器。 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
不是 关联类型族,您可以执行类似
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO, MonadBaseControl IO)
type instance StM Foo a = a
假设我有简单的新类型声明
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
我想创建 MonadBaseControl IO 的 Foo 实例。这应该很容易,因为 ReaderT Int IO 已经是 MonadBaseControl IO 的一个实例。但是,使用 GeneralizedNewtypeDeriving 自动派生它不起作用,因为 MonadBaseControl class 具有关联类型。
如何为 Foo 编写 MonadBaseControl IO 实例? defaultLiftBaseWith 和 defaultRestoreM 应该会有帮助,但要破译它们的类型有点困难。
Foo
既不是 "base" monad,也不是 monad 转换器。 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
不是 关联类型族,您可以执行类似
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO, MonadBaseControl IO)
type instance StM Foo a = a