我有以下代码部分:
run :: State' s a -> s -> (a, Counts)
run s x = do
put x
p <- runState' s
(1, Counts 0 0 0 0)
当我尝试编译它时,我得到的错误与预期类型(a,t0)不符合实际类型(s,计数) - &gt; (A,S,计数)
但是,p的类型不应受任何限制吗?
以下是描述State'数据类型的代码,如果需要的话
newtype State' s a = State' { runState' :: (s, Counts) -> (a, s, Counts) }
instance Functor (State' s) where
fmap = liftM
instance Applicative (State' s) where
pure = return
(<*>) = ap
instance Monad (State' s) where
-- return :: a -> State' s a
return x = State' f
where f = \(s, count) -> (x,s,count <> oneReturn)
-- (>>=) :: State' s a -> (a -> State' s b) -> State' s b
st >>= k = State' (\(s, count) -> let (x,s',count') = runState' st (s, count) in runState' (k x) (s',count' <> oneBind))
instance MonadState (State' s) s where
-- get :: State' s s
get = State' (\(s, count) -> (s, s, count <> oneGet))
-- put :: s -> State' s ()
put s' = State' (\(s, count) -> ((), s', count <> onePut))
旁注,我也很难说我如何得到州“州外”的“计数”部分,所以我可以把它写在屏幕上
或许解释一下应该做什么更有帮助 例如,如果使用函数标签,则使用状态标记树中每个节点的递增数,然后执行run(标签树)30 它应该在状态中放置30,运行标签(因此它从带标签的30开始)然后在屏幕上打印结果树,以及状态的“计数”部分,它跟踪monadic操作和获取的频率/ put已完成
答案 0 :(得分:1)
这里的根本问题是您不恰当地使用do
符号。任何do
代码块都必须具有monadic类型,例如:
example :: String -> IO ()
example s = do { ... }
IO
类型是Monad
。您的do
块的类型为(a, Counts)
。这不是monadic类型。
我认为你想要的是:
run :: State' s a -> s -> (a, Counts)
run s x = (a, c)
where (a, _, c) = runState' s x
但是你写了一些与我不同的东西,我不相信我理解你在哪里。如果这没有意义,请发表评论。