Skip to content
Scalaz integration for Play 2.0
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Scalaz integration for Play 2.0


Add play-scalaz to your project/Build.scala file

val appDependencies = Seq(
  "eu.teamon" %% "play-scalaz" % "0.1.2-SNAPSHOT"

val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
  resolvers += "scalajars repo" at ""


Json deserialization

Play's default json API:

trait Reads[A] {
  def reads(js: JsValue): A
}[A]    // A or Exception
someJson.asOpt[A] // Option[A]

will throw exception in case of invalid json input, or when using asOpt will return Option[A] which contains no information about what went wrong.

play-scalaz provides

trait Readz[A] {
  def reads(js: JsValue): Validation[NonEmptyList[String], A]

case class Foo(a: Int, b: String)

implicit val FooReadz = readz2("a", "b")(Foo)

fromJson[Foo](someJson) // Validation[NonEmptyList[String], Foo]

which will return either the value or list of errors

Promise Monad

Let's say there is code like:

def authenticate(code: String): Promise[Option[Projects]] = requestAccessToken(code).flatMap { tokenOpt => { token => 
    requestAccessToken(token).flatMap { userOpt => { user =>
      } getOrElse Promise.pure(None)
  } getOrElse Promise.pure(None)

def requestAccessToken(code: String): Promise[Option[String]]
def requestUserInfo(accessToken: String): Promise[Option[UserInfo]]
def requestProjects(user: UserInfo): Promise[Option[Projects]]

it gets even more bloated when number of calls grows. But with Promise being Monad:

def authenticate(code: String): Promise[Option[UserInfo]] = (for {
  accessToken <- OptionT(requestAccessToken(code))
  userInfo    <- OptionT(requestUserInfo(accessToken))
  projects    <- OptionT(requestProject(userInfo))
} yield projects).run


Something went wrong with that request. Please try again.