In an effort to understand monads better, I'm attempting to write my own. I'm starting with some non-monadic code, and could use some help translating it into a monad.
Basic idea for this contrived example: for each integer result of a computation, I'd like to track if that integer is even or odd. For example, in 4 + 5 = 9
, we might return (9, Odd)
.
I'd like to be able to chain/compose the calculations with >>=
. For example:
return 1 >>= (+2) >>= (+5) >>= (+7) =result=> (15, Odd)
Right now, I have the following non-monadic code:
data Quality = Odd | Even deriving Show
qual :: Integer -> Quality
qual x = case odd x of
True -> Odd
_ -> Even
type Qualifier = (Integer, Quality)
mkQ :: Integer -> Qualifier
mkQ x = (x, qual x)
plusQ :: Qualifier -> Qualifier -> Qualifier
plusQ (x, _) (y, _) = (x+y, qual (x+y))
chain = plusQ (mkQ 7) . plusQ (mkQ 5) . plusQ (mkQ 2)
What are some ways I can translate the above code into a monad? What are some of the patterns I should look for, and what are common translation patterns for them?
Many thanks in advance!
Quality
. You'll want to look at the State Monad, where your state monad is parameterized byQuality
and your operations(+1)
would turn into state actions. – aaronlevin