For a practical assignment I have to implement MonadSate in Haskell, without using the return function, and by defining get and put in terms of modify, and modify in terms of get and put.
class Monad m ⇒ MonadState m s | m → s where
get :: m s
put :: s → m ()
modify :: (s → s) → m s
I got these laws that I can use:
put s1 >> put s2 ≡ put s2
put s >> get ≡ put s >> return s
get >>= put ≡ return ()
get >>= (λs → get >>= k s) ≡ get >>= (λs → k s s)
I tried the following:
class (Monad m) => MonadState m s | m -> s where
get :: m s
get = modify (\s -> s)
put :: s -> m ()
put s = modify (\_ -> s) >> return ()
modify :: (s -> s) -> m s
modify f = do
s <- get
put (f s) >> get
But I am using return (), which is not allowed
I do not understand how when replacing the old state with the new one, I can return an empty tuple, when the result-type of modify is m s, and not m ()
Piggy-backing on the comment from Fyodor: to distill your problem, you have a value of type
m sand you want a value of typem (). So what you're looking for is some functionf :: m s -> m (). There are a number of ways to implement this function.One way, which you already discovered, is to use
return ():Another way, is simply to use the properties of
Monad, which is a subclass ofFunctor. As a reminder,fmaphas the signaturefmap :: (a -> b) -> f a -> f b. So, you'd need some functiong :: a -> ()such thatThere is only one such implementation of
g.As an added exercise, it's useful to think about what the semantics are when using
(>>)versusfmapin this exercise.