I'm stuck on understanding how Monad works. I'm writing a Parser by using Grammar S->aSb. Input is "a^n b^n for n>=0", e.g "aabb"; Return value for this Parser is a Boolean Value.
Previously by using temporary variables for this Grammar. Now I want to implement this parser by using Monad instead of temporary Variables. But i tried many times und still stuck on this problem.
object Parser {
case class Parser[+A](parse: List[Char] => Option[(A, List[Char])]) {
def accepts(l: List[Char]): Boolean
// If List[Char] is empty after parsing it was successful
= parse(l).map(_._2.isEmpty).getOrElse(false)
// Not sure that this exactly does
def flatMap[B](f: A => Parser[B]): Parser[B] = Parser {
input => parse(input).flatMap { case (x, midput) => f(x).parse(midput) }
}
// a.map( i => i + 1) parses using Parser a and applies function i+1
def map[B](f: A => B): Parser[B] = Parser {
input => parse(input) match {
case Some((t, remains)) => Some((f(t), remains))
case _ => None
}
}
// a.orElse(b) tries to use Parser a first
// If a returns None it tries Parser b
// If b also returns None all rules are exhausted
def orElse[B](that: Parser[B]): Parser[Either[A, B]] = Parser {
input => parse(input) match {
case Some((p, remains)) => Some((Left(p), remains))
case None => that.parse(input) match {
case Some((p, remains)) => Some((Right(p), remains))
case None => None
}
}
}
}
// Not sure if this is correct
def unit[T](x: T): Parser[T] = Parser {
_ => Some((x, List()))
}
// Consumes c if possible
def char(c: Char): Parser[Unit] = Parser {
case x :: rest if c == x => Some(((), rest))
case _ => None
}
def main(args: Array[String]): Unit = {
val S: Parser[Int]
= char('a').flatMap { _ =>
S.flatMap { i =>
char('b').map { _ =>
i + 1
}
}
}.orElse(unit(0)).map(_.merge)
S.accepts("".toList) // true
S.accepts("aaabbb".toList) // true
S.accepts("aaa".toList) // false
S.accepts("bbbaaa".toList) // false
}
}