Last active
August 29, 2015 14:09
-
-
Save mkrcah/512dd7a8228833bb44ba to your computer and use it in GitHub Desktop.
Intro into Scalaz disjunction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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