首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仪器状态单

仪器状态单
EN

Stack Overflow用户
提问于 2019-09-02 21:33:03
回答 1查看 126关注 0票数 4

我试图为MonadMonadState实例提供计算(>>=), return, getput操作数量的State'实例。

代码语言:javascript
复制
data Counts = Counts { binds   :: Int
                 , returns :: Int
                 , gets    :: Int
                 , puts    :: Int
                 }

newtype State' s a = State' { runState' :: (s, Counts) -> (a, s, Counts) }

这就是我已经做过的,就我所理解的情况而言,这段代码应该可以工作:

代码语言:javascript
复制
instance Monad State' where
  return     = State' ( \(s, counts) -> (x, s, counts mappend oneReturn))
  (>>=) st f = State' ( \(s, counts) -> let (x, s', counts') = runState' (s, counts) in runState' ((f x), (s', counts' mappend oneBind)) )

instance Monad m => MonadState m State' where
   get    = State' ( \(s, counts) -> (s, s, counts mappend oneGet) )
   put st = State' ( \(s, counts) -> ((), st, counts mappend onePut) )

但我得到了一条错误信息:

期待再给‘State'’一个参数 期望种类‘* -> *’,但‘State'’有种类‘* -> * -> *’

为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-02 22:09:44

重点在句子里

Expected kind ‘* -> *’, but ‘State'’ has kind ‘* -> * -> *’

如果使用State'命令检查GHCi的类型,您将看到State'具有GHCi * -> * -> *,简单地说,这意味着它需要被两种类型的*参数化才能生成最终的*类型。正如您所看到的,Monad只限于* -> *。例如,Maybe是一个Monad,而Maybe Int不是。

要解决您的情况,您需要将状态类型应用于State',然后您将能够将其声明为Monad:

代码语言:javascript
复制
instance Monad (State' s) where

第二部分中的错误有点概念性--声明中的m是什么?MonadStateMonad的一个子类,所以MonadState的每个实例都是Monad的实例。考虑到这一点,正确的表示法应该是有意义的:

代码语言:javascript
复制
instance MonadState s (State' s) where

您不想提到这个Monad -它是从类声明派生出来的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57762867

复制
相关文章

相似问题

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