Michael
Michael

Reputation: 42100

How to write it with for-comprehension instead of nested flatMap calls?

I am trying to translate examples from this article to Scala.

So I defined a monadic class Parser with success as return function.

class Parser[A](val run: String => List[(A, String)]) {
  def apply(s: String) = run(s)
  def flatMap[B](f: A => Parser[B]): Parser[B] = {
    val runB = {s: String => for((r, rest) <- run(s); rb <- f(r)(rest)) yield rb}
    new Parser(runB)
  }
}

def success[A](a:A):Parser[A] = {
  val run = {s:String => List((a, s))}
  new Parser(run)
}

I defined also a new parser item to return the 1st character of the input.

def item(): Parser[Char] = {
  val run = {s: String => if (s.isEmpty) Nil else List((s.head, s.tail))}
  new Parser(run)
}

Now I am defining a new parser item12: Parser[(Char, Char)] to return a pair of 1st and 2nd characters

 def item12():Parser[(Char, Char)] = 
   item().flatMap(a => (item().flatMap(b => success(a, b))))

I would like to write it with for-comprehension instead of nested flatMap calls. I understand that I need to define a map method for the Parser. How would you do that ?

Upvotes: 1

Views: 168

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170899

I understand that I need to define a map method for the Parser. How would you do that ?

def map[B](f: A => B): Parser[B] = {
  val runB = {s: String => ???} // you need to call run and f here
  new Parser(runB)
}

I am leaving the body of runB in case you want to do it yourself.

Upvotes: 2

Related Questions