プログラミングHaskell 8.7 空白の扱い

実用的なパーサーは、入力文字列中の「トークン」の前後に任意の空白を許す。...(中略)...あるトークンのパーサーを適用する際、前後の空白を無視する部品を定義する。

  def token[A](p: Parser[A]): Parser[A] = for {
    _ <- space
    v <- p
    _ <- space
  } yield v

tokenを利用すると、前後の空白を無視するパーサーを定義するのが簡単になる。

  def identifire: Parser[String] = token(ident) // 前後の空白を無視する識別子のパーサー
  def natural: Parser[Int] = token(nat) // 前後の空白を無視する自然数パーサー
  def symbol(xs: String): Parser[String] = token(string(xs)) // 前後の空白を無視する特定の文字列パーサー

自然数のリストを解析するパーサー。

def naturalList: Parser[List[Int]] = for {
    _ <- symbol("[")
    n <- natural
    ns <- many(for {
      _ <- symbol(",")
      nn <- natural
    } yield nn)
    _ <- symbol("]")
  } yield (n :: ns)

実行。

  println("sample21: " + parse(naturalList)(" [1, 2, 3] "))
  println("sample22: " + parse(naturalList)("[1, 2,]"))
sample21: List((List(1, 2, 3),))
sample22: List()

ほう!!