Skip to content

Instantly share code, notes, and snippets.

@julienrf
Created September 12, 2012 12:23
Show Gist options
  • Save julienrf/3706278 to your computer and use it in GitHub Desktop.
Save julienrf/3706278 to your computer and use it in GitHub Desktop.
A bottom up approach to category theory: Functors
case class Contact(name: String, email: String)
def byId(id: Long): Option[Contact]
def all: List[Contact]
def listMap[A, B](f: A => B)(xs: List[A]): List[B] = xs match {
case Nil => Nil
case x :: xs => f(x) :: listMap(f)(xs)
}
def listMap[A, B](f: A => B, xs: List[A]): List[B] = xs match {
case Nil => Nil
case x :: xs => f(x) :: listMap(f, xs)
}
def listToJson(contacts: List[Contact]): List[JsObject] = contacts match {
case Nil => Nil
case c :: cs =>
val contactJson = Json.obj(
"name" -> c.name,
"email" -> c.email
)
contactJson :: listToJson(cs)
}
object Application extends Controller {
def list = Action {
Ok(<contacts>{ listToXml(Contacts.all) }</contacts>)
}
def listToXml(contacts: List[Contact]): List[Node] = contacts match {
case Nil => Nil
case c :: cs =>
val contactXml =
<contact>
<name>{ c.name }</name>
<email>{ c.email }</email>
</contact>
contactXml :: listToXml(cs)
}
}
def optionMap[A, B](f: A => B)(maybeA: Option[A]): Option[B] = maybeA match {
case None => None
case Some(a) => Some(f(a))
}
def listAsJson = Action {
Ok(Json.toJson(listMap(Contacts.all)(toJson)))
}
def readAsJson(id: Long) = Action {
optionMap(Contacts.byId(id))(toJson) match {
case Some(json) => Ok(json)
case None => NotFound
}
}
def toXml(c: Contact): Node =
<contact>
<name>{ c.name }</name>
<email>{ c.email }</email>
</contact>
def toJson(c: Contact): JsObject =
Json.obj(
"name" -> c.name,
"email" -> c.email
)
val listToXml = listMap(toXml) _
val listToJson = listMap(toJson) _
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment