First, just some quick context. I'm going through the Haskell Programming From First Principles book, and ran into the following exercise.
Try writing a Parser that does what
string
does, but usingchar
.
I couldn't figure it out, so I checked out the source for the implementation. I'm currently trying to wrap my head around it. Here it is:
class Parsing m => CharParsing m where
-- etc.
string :: CharParsing m => String -> m String
string s = s <$ try (traverse_ char s) <?> show s
My questions are as follows, from most to least specific.
Why is
show
necessary?Why is
s <$
necessary? Doesn'ttraverse char s <?> s
work the same? In other words, why do we throw away the results of the traversal?What is going on with the traversal? I get what a list traversal does, so I guess I'm confused about the Applicative/Monad instances for Parser. On a high level, I get that the traversal applies
char
, which has typeCharParsing m => Char -> m Char
, to every character in strings
, and then collects all the results into something of typeParser [Char]
. So the types make sense, but I have no idea what's going on in the background.
Thanks in advance!