I am trying to create a monad that combines state and error processing, like this
import Control.Monad
data Result a e = Ok a | Error e
newtype StateError s e a = StateError { runStateError :: s -> (Result a e, s) }
instance Monad (StateError s e) where
return x = StateError $ \s -> (Ok x, s)
m >>= f = StateError $
\s -> case runStateError m s of
(Ok x, s') -> runStateError (f x) s'
e -> e
get = StateError $ \s -> ((Ok s), s)
put s = StateError $ \_ -> ((Ok ()), s)
main = return ()
When I compile, I receive this error, which I do not know how to fix:
StateError.hs:13:18: error:
• Couldn't match type ‘a’ with ‘b’
‘a’ is a rigid type variable bound by
the type signature for:
(>>=) :: forall a b.
StateError s e a -> (a -> StateError s e b) -> StateError s e b
at StateError.hs:10:5-7
‘b’ is a rigid type variable bound by
the type signature for:
(>>=) :: forall a b.
StateError s e a -> (a -> StateError s e b) -> StateError s e b
at StateError.hs:10:5-7
Expected type: (Result b e, s)
Actual type: (Result a e, s)
• In the expression: e
In a case alternative: e -> e
In the expression:
case runStateError m s of
(Ok x, s') -> runStateError (f x) s'
e -> e
• Relevant bindings include
e :: (Result a e, s) (bound at StateError.hs:13:13)
f :: a -> StateError s e b (bound at StateError.hs:10:9)
m :: StateError s e a (bound at StateError.hs:10:3)
(>>=) :: StateError s e a
-> (a -> StateError s e b) -> StateError s e b
(bound at StateError.hs:10:5)
|
13 | e -> e
| ^
What am I doing wrong here? I think the problem is the difficulty of matching the two results of the case
Expected type: (Result b e, s)
Actual type: (Result a e, s)
like force a
to be a b
, or something alike, but I don't know how to solve this.
In addition, I am also receiving this error:
StateError.hs:7:10: error:
• No instance for (Applicative (StateError s e))
arising from the superclasses of an instance declaration
• In the instance declaration for ‘Monad (StateError s e)’
|
7 | instance Monad (StateError s e) where
| ^^^^^^^^^^^^^^^^^^^^^^
This asks me to instantiate Applicative
, so I would appreciate some guidance on what to do here.
Thanks