Skip to content

Instantly share code, notes, and snippets.

@mkrcah
Last active August 29, 2015 14:09
Show Gist options
  • Save mkrcah/512dd7a8228833bb44ba to your computer and use it in GitHub Desktop.
Save mkrcah/512dd7a8228833bb44ba to your computer and use it in GitHub Desktop.
Intro into Scalaz disjunction
import net.liftweb.http.JsonResponse
import scalaz._
import net.liftweb.json.JsonDSL._
// Fabricated errors that we might encounter
trait ParseError
case class ExtractError(s:String) extends ParseError
case class ConversionError(s: String) extends ParseError
case class SqrtError(n: Int) extends ParseError
// Let's define a couple of methods that might end with an error
// and are supposed to be called in a chain.
// Notice different error types on the left of the disjunction
def extractSecondToken(s: String): ExtractError \/ String = ???
def toInt(str: String): ConversionError \/ Int = ???
def sqrt(x: Int): SqrtError \/ Double = ???
// Let's chain the functions without worrying about error handling.
// Variable `res` will have type ParserError \/ Double
val res = for {
token <- extractSecondToken("sqrt -5")
n <- toInt(token)
sqrt <- sqrt(n)
} yield sqrt
// This for-comprehension desugars to a sequence of flatMaps,
// which converts a disjunction of a disjunction into a simple disjunction.
// Let's map the result to either ok or bad responses
// valueOr takes the right if it's defined. Otherwise map on the left.
res.map(toOkResponse).valueOr(toBadResponse)
def toOkResponse(n: Double) = JsonResponse("result" -> n)
def toBadResponse(e: ParseError) = JsonResponse("errorMsg" -> e.toString)
// And of course, all operations like map, exists, foreach works on the right
val accounts: ParseError \/ List[String] = ???
accounts.exists(_.nonEmpty) // true iff list is defined and is nonempty
for {
a <- \/-(4)
b <- \/-(5)
c = 3
} yield a+b+c //returns \/-(12)
for {
a <- \/-(4)
b <- -\/("did a boo boo")
c = 3
} yield a+b+c //returns -\/("did a boo boo")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment