Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Monad[Parser], and a usage example.

  • Loading branch information...
commit 8bf1d2a090cf56d33e11c554e974ea3c82b7b37f 1 parent 74a7af2
Jason Zaugg authored
26 core/src/main/scala/scalaz/std/util/parsing/combinator/Parser.scala
View
@@ -0,0 +1,26 @@
+package scalaz
+package std
+package util
+package parsing
+package combinator
+
+import scala.util.parsing.combinator
+
+trait Parsers {
+ class ParsersW[P <: combinator.Parsers](val parser: P) {
+ type Parser[A] = parser.Parser[A]
+ def instance: Monad[Parser] = new Monad[Parser] {
+ def pure[A](a: => A): Parser[A] = parser.success(a)
+ def bind[A, B](fa: Parser[A])(f: (A) => Parser[B]): Parser[B] = fa flatMap f
+ }
+ }
+
+ // A few type gymnastics are required to target the path-dependent type
+ //
+ // The return type is Monad[p.type#Parser]
+ //
+ // This way seems to work without -Ydependent-method-types, yay!
+ def parserMonad[P <: combinator.Parsers](p: P) = new ParsersW[P](p).instance
+}
+
+object Parser extends Parsers
26 example/src/main/scala/scalaz/example/ParserUsage.scala
View
@@ -0,0 +1,26 @@
+package scalaz.example
+
+import util.parsing.combinator.RegexParsers
+import collection.immutable.List
+import scalaz._
+
+object ParserUsage extends App {
+
+ object testParser extends RegexParsers {
+ val parsers: List[Parser[List[String]]] = List(1, 2, 3).map(repN(_, """\d+""".r))
+
+ def apply(s: String): ParseResult[List[List[String]]] = {
+ import scalaz.syntax.Syntax.applicative._ // for _.sequence
+ import scalaz.std.List._ // for Traverse[List]
+ import scalaz.std.util.parsing.combinator.Parser.parserMonad
+
+ implicit val M: Monad[Parser] = parserMonad(testParser)
+ val sequence: Parser[List[List[String]]] = parsers.sequence
+ parseAll(sequence, s)
+ }
+ }
+
+ // http://stackoverflow.com/questions/7785762/writing-type-class-instances-for-nested-classes-in-scala
+ val result: List[List[String]] = testParser("1 2 2 3 3 3").getOrElse(Nil)
+ assert(result == List(List("1"), List("2", "2"), List("3", "3", "3")))
+}
Please sign in to comment.
Something went wrong with that request. Please try again.