Last Updated: February 25, 2016
·
1.392K
· teamon

Shorten your Play 2.0 Promise code with scalaz

Let's say there is code like:

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

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

A lot of nested map/flatMaps, it gets even more bloated when number of calls grows.

But Promise is a Monad!

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

Play's Monad instance if available in http://github.com/teamon/play-scalaz package

1 Response
Add your response

what do OptionT and run do exactly?

over 1 year ago ·