gpt4 book ai didi

haskell - MonadBaseControl IO ... StateT 实现

转载 作者:行者123 更新时间:2023-12-03 22:10:14 26 4
gpt4 key购买 nike

我想弄清楚如何实现 MonadBaseControl 的实例对于 Foo 类型,它是 StateT 实例的新型包装器。你会认为它会像 this 一样实现但情况似乎并非如此。我假设状态块是导致这里问题的原因,那么有没有办法删除它?

代码:

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)

所以对于 StateT Foo 的版本我们也可以这样写:
instance MonadBaseControl IO Foo where
type StM Foo a = (a, Int)

关于haskell - MonadBaseControl IO ... StateT 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33558234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com