This is a new version of my previous question
We can define a parser as type Parser[A] = String => List[(A, String)]
. The parser takes an input string an
<*>
(terrible name) apparently has this signature:
<*>[B](f: F[(A) ⇒ B]): F[B]
So let's just chase the types through, thinking about what a parser should do - helped by the fact that List
already implements flatMap
:
def <*>[A, B](fa: Parser[A], fab: Parser[(A) => B]) =
new Parser[B] {
def apply(s: String) =
for {
(a, rem1) ← fa(s)
(ab, rem2) ← fab(rem1)
} yield (ab(a), rem2)
}
That looks like a sensible implementation - parse a
first, then parse ab
from the remainder, and then we have our result.
That example is too symbolic for me and I don't know Haskell - if you can find documentation for the <$
and <|>
then I'll give it a go.