Skip to content

Instantly share code, notes, and snippets.

@wrwills
Created October 8, 2010 14:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save wrwills/616871 to your computer and use it in GitHub Desktop.
Save wrwills/616871 to your computer and use it in GitHub Desktop.
applicative_example
import scalaz._
/**
* A simple example of how applicative functors can shorten code
* adapted from chapter 8? of Real World Haskell
*/
object OptionGolf {
import Scalaz._
val moviel = Map("title" -> "South Park",
"user" -> "Terrence",
"rating" -> "3")
val incompleteMovie = Map("name" -> "Jaws")
case class MovieReview(revTitle: String, revUser: String, revReview: String)
/*
* the ugly way
*/
def rev1(movie: Map[String,String]): Option[MovieReview] =
movie get "title" match {
case None => None
case Some(title) => movie get "user" match {
case None => None
case Some(user) => movie get "rating" match {
case None => None
case Some(rating) => Some(MovieReview(title,user,rating))
}
}
}
/*
* using monads: slightly better
*/
def rev2(movie: Map[String,String]): Option[MovieReview] =
for (title <- movie get "title";
user <- movie get "user";
rating <- movie get "rating")
yield MovieReview (title,user,rating)
/*
* but with applicative functors you can express it all in one line
*/
def rev3(movie: Map[String,String]): Option[MovieReview] =
movie.get("title") <*> (movie.get("user") <*> (movie.get("rating") ∘ MovieReview.curried))
def main(args: Array[String]) {
println(rev3(moviel))
println(rev3(incompleteMovie))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment