Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Monad[Parser], and a usage example.

  • Loading branch information...
commit 8bf1d2a090cf56d33e11c554e974ea3c82b7b37f 1 parent 74a7af2
Jason Zaugg authored October 16, 2011
26  core/src/main/scala/scalaz/std/util/parsing/combinator/Parser.scala
... ...
@@ -0,0 +1,26 @@
  1
+package scalaz
  2
+package std
  3
+package util
  4
+package parsing
  5
+package combinator
  6
+
  7
+import scala.util.parsing.combinator
  8
+
  9
+trait Parsers {
  10
+  class ParsersW[P <: combinator.Parsers](val parser: P) {
  11
+    type Parser[A] = parser.Parser[A]
  12
+    def instance: Monad[Parser] = new Monad[Parser] {
  13
+      def pure[A](a: => A): Parser[A] = parser.success(a)
  14
+      def bind[A, B](fa: Parser[A])(f: (A) => Parser[B]): Parser[B] = fa flatMap f
  15
+    }
  16
+  }
  17
+
  18
+  // A few type gymnastics are required to target the path-dependent type
  19
+  //
  20
+  // The return type is Monad[p.type#Parser]
  21
+  //
  22
+  // This way seems to work without -Ydependent-method-types, yay!
  23
+  def parserMonad[P <: combinator.Parsers](p: P) = new ParsersW[P](p).instance
  24
+}
  25
+
  26
+object Parser extends Parsers
26  example/src/main/scala/scalaz/example/ParserUsage.scala
... ...
@@ -0,0 +1,26 @@
  1
+package scalaz.example
  2
+
  3
+import util.parsing.combinator.RegexParsers
  4
+import collection.immutable.List
  5
+import scalaz._
  6
+
  7
+object ParserUsage extends App {
  8
+
  9
+  object testParser extends RegexParsers {
  10
+    val parsers: List[Parser[List[String]]] = List(1, 2, 3).map(repN(_, """\d+""".r))
  11
+
  12
+    def apply(s: String): ParseResult[List[List[String]]] = {
  13
+      import scalaz.syntax.Syntax.applicative._ // for _.sequence
  14
+      import scalaz.std.List._ // for Traverse[List]
  15
+      import scalaz.std.util.parsing.combinator.Parser.parserMonad
  16
+
  17
+      implicit val M: Monad[Parser] = parserMonad(testParser)
  18
+      val sequence: Parser[List[List[String]]] = parsers.sequence
  19
+      parseAll(sequence, s)
  20
+    }
  21
+  }
  22
+
  23
+  // http://stackoverflow.com/questions/7785762/writing-type-class-instances-for-nested-classes-in-scala
  24
+  val result: List[List[String]] = testParser("1 2 2 3 3 3").getOrElse(Nil)
  25
+  assert(result == List(List("1"), List("2", "2"), List("3", "3", "3")))
  26
+}

0 notes on commit 8bf1d2a

Please sign in to comment.
Something went wrong with that request. Please try again.