Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
scalaz bindings for gll-combinators
Scala
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
project
src
README.org

README.org

README.org

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 https://github.com/stew/scalaz-gll.git
$ 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 => nameP.map(Person(first,_)) }

5 TODO

  • Should probably have a separate semigroup instance so that Parser[A] is a semigroup if A is a semigroup but not a monoid
Something went wrong with that request. Please try again.