Reputation: 65
I have the following section of code:
run :: State' s a -> s -> (a, Counts)
run s x = do
put x
p <- runState' s
(1, Counts 0 0 0 0)
When I try to compile this, I get the error couldn't match expected type (a, t0) with actual type (s,counts) -> (a,s,counts)
However, p's type shouldn't be constrained by anything should it?
The following is the code describing the State' datatype, in case it is needed
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))
Side note, I am also stumped as to how I would get the "count" part of the state' out of the state' so I can write it on the screen
Maybe it's more helpful to explain what run is supposed to do.
For instance if you use a function label, that labels each node in a tree with an incrementing number using a state, and then execute run (label tree) 30
It is supposed to put 30 in the state, run label (so it starts at 30 with labeling) then print the resulting tree on the screen, as well as the "count"portion of the state, which tracks how often monadic operations and get/put are done on it
Upvotes: 0
Views: 791
Reputation: 5992
The fundamental problem here is that you're using do
notation inappropriately. Any block of do
code must have a monadic type, such as:
example :: String -> IO ()
example s = do { ... }
The type IO
is a Monad
. Your do
block has type (a, Counts)
. This is not a monadic type.
I think what you want is this:
run :: State' s a -> s -> (a, Counts)
run s x = (a, c)
where (a, _, c) = runState' s x
But you wrote something so different from that that I'm not confident I understand where you're going with it. Leave a comment if this doesn't make sense.
Upvotes: 1