我试图为Monad和MonadState实例提供计算(>>=), return, get和put操作数量的State'实例。
data Counts = Counts { binds :: Int
, returns :: Int
, gets :: Int
, puts :: Int
}
newtype State' s a = State' { runState' :: (s, Counts) -> (a, s, Counts) }这就是我已经做过的,就我所理解的情况而言,这段代码应该可以工作:
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'’有种类‘* -> * -> *’
为什么?
发布于 2019-09-02 22:09:44
重点在句子里
Expected kind ‘* -> *’, but ‘State'’ has kind ‘* -> * -> *’
如果使用State'命令检查GHCi的类型,您将看到State'具有GHCi * -> * -> *,简单地说,这意味着它需要被两种类型的*参数化才能生成最终的*类型。正如您所看到的,Monad只限于* -> *。例如,Maybe是一个Monad,而Maybe Int不是。
要解决您的情况,您需要将状态类型应用于State',然后您将能够将其声明为Monad:
instance Monad (State' s) where第二部分中的错误有点概念性--声明中的m是什么?MonadState是Monad的一个子类,所以MonadState的每个实例都是Monad的实例。考虑到这一点,正确的表示法应该是有意义的:
instance MonadState s (State' s) where您不想提到这个Monad -它是从类声明派生出来的。
https://stackoverflow.com/questions/57762867
复制相似问题