首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MonadBaseControl IO ..。StateT实现

MonadBaseControl IO ..。StateT实现
EN

Stack Overflow用户
提问于 2015-11-06 02:01:26
回答 1查看 254关注 0票数 4

我试图找出如何为Foo类型实现MonadBaseControl实例,Foo是StateT实例的新类型包装器。您可能会认为它会像一样实现,但情况似乎并非如此。我假设这个州的问题是在这里引起的,那么有什么办法可以解决这个问题吗?

代码:

代码语言:javascript
复制
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 

错误:

代码语言:javascript
复制
 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-06 02:47:13

为了避免UndecidableInstances,链接的答案扩展了一个类型家族,为了人类的可读性,它真的不应该这样做。也就是说,他写道

代码语言:javascript
复制
instance MonadBaseControl IO Foo where
    type StM Foo a = a

当人们可能会考虑写

代码语言:javascript
复制
instance MonadBaseControl IO Foo where
    type StM Foo a = StM (ReaderT Int IO) a

为了更清楚地说明如何为给定的新型包装选择正确的右侧。使用类似的更改(和UndecidableInstances),您的代码可以正常工作。如果您想要避免UndecidableInstances,可以在链接的答案中进行相同的扩展;一个询问ghci应该展开什么的示例如下所示:

代码语言:javascript
复制
> :kind! forall a. StM (StateT Int IO) a
forall a. StM (StateT Int IO) a :: *
= (a, Int)

因此,对于StateT版本的Foo,我们也可以编写:

代码语言:javascript
复制
instance MonadBaseControl IO Foo where
    type StM Foo a = (a, Int)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33558234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档