scalaz bindings for gll-combinators
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

This package adds support for using some scalaz type-classes with gll-combinators Parsers.

1 Install

Clone the github repository, and publish it to your local ivy2:

$ git clone
$ cd scalaz-gll
$ sbt publish-local

2 Configure SBT

Add the following libraryDependency to your project:

"org.vireo" %% "scalaz-gll" % "0.1"

3 Mix in the ScalazInstances trait:

In order to get access to the implicits that add type class instances for scalaz, you need to mixin the scalaz.gll.ScalazInstances trait to your Parser:

import com.codecommit.gll._
import scalaz.gll.ScalazInstances

class MyParser extends RegexParsers with ScalazInstances {

4 Supported Categories

4.1 Monoid / (Semigroup)

Parser[A] is a monoid if A is a monoid.

Since string is a monoid:

val uppercase : Parser[String] = "[A-Z]"r
val lowercases : Parser[String] = "[a-z]*"r

val capitalized : Parser{String] = uppercase |+| lowercases
// which is equivalent to:
val capitalized0 : Parser[String] = (uppercase ~ lowercases) ^^ (_ ++ _)

List is a monoid, where mzero is List(). The derived mzero for Parser[List[A]] is a parser which consumes no input and produces an empty List[A]. When we have a monoid, we can use scalaz’s provided suml function:

val listOfParsers = List[Parser[String]]("a","b","c","d")

val abcdParser : Parser[String] = listOfParsers.suml
// which is equivalent to
val abcdParser : Parser[String] = "abcd"

4.2 Pointed

Point[Parser[A]] will create a parser which consumes no input and produces an A. so:

val fooP : Parser[String] = "foo"
val pointP = 1111.point[Parser]

// a parser that when parsing the string "foo" will produce: 1111 ~ "foo"
val p = pointP ~ fooP

4.3 Applicative

This is taken right out of the specs included in src/test:

case class Person(first: String, last: String)
// BTW: take it from a guy named O'Connor that the following is sucky
val nameP : Parser[String] = regex("[A-Za-z]*"r)

val applicativePerson: Parser[Person] = (nameP |@| nameP)(Person)
// could also be written as:
val applyPerson = ^(nameP, nameP)(Person)

4.4 Monad

Same as above, but:

val monadPerson = for {
    first <- nameP
    last <- nameP
} yield(Person(first,last))

// however that would have worked without a monad instance, so to insist 
// on using the monad instance:
val monadPerson2 = nameP >>= { first =>,_)) }


  • Should probably have a separate semigroup instance so that Parser[A] is a semigroup if A is a semigroup but not a monoid