为newtype创建MonadBaseControl实例 [英] creating MonadBaseControl instance for newtype
问题描述
假设我有简单的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应该是有帮助的,但是解密它们的类型有点困难。
/ code>既不是基本monad,也不是monad变换器。 defaultLiftBaseWith
在这里不会有帮助,因为您希望 Foo
的实例与<$ code> ReaderT Int IO 。 首先,使用GND获取无聊的实例:
{ - #LANGUAGE GeneralizedNewtypeDiving##}
导入Control.Monad.Trans.Control
导入Control.Monad.Base
导入Control.Monad.Reader
导入控制。应用
newtype Foo a = Foo {unFoo :: ReaderT Int IO a}
派生(Monad,Applicative,Functor,MonadBase IO)
MonadBaseControl IO
的实例只删除newtype,使用 ReaderT
实例,并将结果放回新类型:
实例MonadBaseControl IO Foo其中
类型StM Foo a = a
liftBaseWith f = Foo $ liftBaseWith $ \q - > f(q。unFoo)
restoreM = Foo。 restoreM
请注意,如果 StM
不是关联类型的家庭,你可以做一些类似的事情:
newtype Foo a = Foo {unFoo :: (Monad,Applicative,Functor,MonadBase IO,MonadBaseControl IO)
类型实例StM Foo a = a
Suppose I have simple newtype declaration
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
I want to make Foo instance of MonadBaseControl IO. It should be easy, since ReaderT Int IO is already an instance of MonadBaseControl IO. However, automatically deriving it using GeneralizedNewtypeDeriving doesn't work, because MonadBaseControl class has an associated type.
How can one write a MonadBaseControl IO instance for Foo? defaultLiftBaseWith and defaultRestoreM should be helpful, but it's a bit hard to decipher their types.
Foo
is neither a "base" monad, nor a monad transformer. defaultLiftBaseWith
won't be helpful here, since you want the instance for Foo
to be identical to the one for ReaderT Int IO
.
First, use GND to get the boring instances:
{-# 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)
The instance for MonadBaseControl IO
just removes the newtype, uses the functions from the ReaderT
instance, and puts the result back in the newtype:
instance MonadBaseControl IO Foo where
type StM Foo a = a
liftBaseWith f = Foo $ liftBaseWith $ \q -> f (q . unFoo)
restoreM = Foo . restoreM
Note that if StM
wasn't an associated type family, you could do something like
newtype Foo a = Foo { unFoo :: ReaderT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO, MonadBaseControl IO)
type instance StM Foo a = a
这篇关于为newtype创建MonadBaseControl实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!