It took me an oddly long time to realize that parser combinators make a lot of sense in do-notation.
My inclination was always to write something like
(a *> (fmap f b)) *< c
but why do that when you could do this
do
_ <- a
b' <- b
_ <- c
pure (f b')