MonadBaseControl IO ... StateT 实现
MonadBaseControl IO ... StateT Implementation
我正在尝试弄清楚如何实现 MonadBaseControl for type Foo which is a newtype wrapper around a StateT instance. You would think it would be implemented just like 的实例,但情况似乎并非如此。我假设 state piece 导致了这里的问题,那么有没有办法删除它?
代码:
newtype Foo a = Foo { unFoo :: StateT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO)
instance MonadBaseControl IO Foo where
type StM Foo a = a
liftBaseWith f = Foo $ liftBaseWith $ \q -> f (q . unFoo)
restoreM = Foo . restoreM
错误:
Couldn't match type ‘a’ with ‘(a, Int)’
‘a’ is a rigid type variable bound by
the type signature for restoreM :: StM Foo a -> Foo a
Expected type: a -> StateT Int IO a
Actual type: StM (StateT Int IO) a -> StateT Int IO a
Relevant bindings include
restoreM :: StM Foo a -> Foo a
In the second argument of ‘(.)’, namely ‘restoreM’
In the expression: Foo . restoreM
为了避免 UndecidableInstances
,链接的答案扩展了一个类型系列,为了人类的可读性,它确实不应该有。也就是说,他写道
instance MonadBaseControl IO Foo where
type StM Foo a = a
什么时候可以考虑写作
instance MonadBaseControl IO Foo where
type StM Foo a = StM (ReaderT Int IO) a
更清楚如何为给定的新类型包装选择正确的右侧。通过类似的更改(和 UndecidableInstances
),您的代码可以正常工作。如果你想避免 UndecidableInstances
,你可以在链接的答案中做同样的扩展;询问 ghci 扩展应该是什么的示例如下所示:
> :kind! forall a. StM (StateT Int IO) a
forall a. StM (StateT Int IO) a :: *
= (a, Int)
所以对于 Foo
的 StateT
版本,我们也可以这样写:
instance MonadBaseControl IO Foo where
type StM Foo a = (a, Int)
我正在尝试弄清楚如何实现 MonadBaseControl for type Foo which is a newtype wrapper around a StateT instance. You would think it would be implemented just like
代码:
newtype Foo a = Foo { unFoo :: StateT Int IO a }
deriving (Monad, Applicative, Functor, MonadBase IO)
instance MonadBaseControl IO Foo where
type StM Foo a = a
liftBaseWith f = Foo $ liftBaseWith $ \q -> f (q . unFoo)
restoreM = Foo . restoreM
错误:
Couldn't match type ‘a’ with ‘(a, Int)’
‘a’ is a rigid type variable bound by
the type signature for restoreM :: StM Foo a -> Foo a
Expected type: a -> StateT Int IO a
Actual type: StM (StateT Int IO) a -> StateT Int IO a
Relevant bindings include
restoreM :: StM Foo a -> Foo a
In the second argument of ‘(.)’, namely ‘restoreM’
In the expression: Foo . restoreM
为了避免 UndecidableInstances
,链接的答案扩展了一个类型系列,为了人类的可读性,它确实不应该有。也就是说,他写道
instance MonadBaseControl IO Foo where
type StM Foo a = a
什么时候可以考虑写作
instance MonadBaseControl IO Foo where
type StM Foo a = StM (ReaderT Int IO) a
更清楚如何为给定的新类型包装选择正确的右侧。通过类似的更改(和 UndecidableInstances
),您的代码可以正常工作。如果你想避免 UndecidableInstances
,你可以在链接的答案中做同样的扩展;询问 ghci 扩展应该是什么的示例如下所示:
> :kind! forall a. StM (StateT Int IO) a
forall a. StM (StateT Int IO) a :: *
= (a, Int)
所以对于 Foo
的 StateT
版本,我们也可以这样写:
instance MonadBaseControl IO Foo where
type StM Foo a = (a, Int)