为newtype创建MonadBaseControl实例

假设我有简单的newtype声明

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既不是“基地”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的实例只是删除MonadBaseControl IO ,使用ReaderT实例中的函数,并将结果放回到newtype中:

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 
链接地址: http://www.djcxy.com/p/43457.html

上一篇: creating MonadBaseControl instance for newtype

下一篇: Why is there no `