Skip to content

Instantly share code, notes, and snippets.

@davegurnell
Created February 19, 2015 20:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davegurnell/6ca1e1857592b1053ab0 to your computer and use it in GitHub Desktop.
Save davegurnell/6ca1e1857592b1053ab0 to your computer and use it in GitHub Desktop.
Notes on error handling and monads from London Scala Dojo on 19th February 2015
def userId(username: String): Option[Int] =
Some(1)
def mostRecentOrderId(userId: Int): Option[Int] =
Some(2)
def orderCost(orderId: Int): Option[Int] =
Some(3)
def mostRecentOrderCost(username: String): Option[Int] =
userId("Noel") match {
case None => None
case Some(userId) =>
mostRecentOrderId(userId) match {
case None => None
case Some(orderId) =>
orderCost(orderId) match {
case None => None
case Some(cost) => Some(cost)
}
}
}
def flatMap(startValue: Option[Int], func: Int => Int): Option[Int] = {
startValue match {
case None => None
case Some(intermediateValue) =>
Some(func(intermediateValue))
}
}
def flatMap(startValue: Option[Int], func: Int => Option[Int]): Option[Int] = {
startValue match {
case None => None
case Some(intermediateValue) =>
func(intermediateValue)
}
}
def mostRecentOrderCost(username: String): Option[Int] =
sequence(
userId("Noel"),
(userId: Int) => {
sequence(
mostRecentOrderId(userId),
(orderId: Int) => {
sequence(
orderCost(orderId),
(orderCost: Int) => {
Some(orderCost)
}
)
}
)
}
)
def mostRecentOrderCost(username: String): Option[Int] =
userId("Noel").flatMap { (uid: Int) =>
mostRecentOrderId(uid).flatMap { (oid: Int) =>
orderCost(oid).map { (cost: Int) =>
cost
}
}
}
def mostRecentOrderCost(username: String): Option[Int] =
userId("Noel").flatMap(mostRecentOrderId).flatMap(orderCost)
def mostRecentOrderCost(username: String): Option[Int] =
for {
uid <- userId("Noel")
oid <- mostRecentOrderId(uid)
cost <- orderCost(oid)
} yield cost
// Sealed traits
sealed trait Shape
final case class Circle(radius: Int) extends Shape
final case class Square(side: Int) extends Shape
final case class Rectangle(width: Int, height: Int) extends Shape
def readShapeFromFile: Shape = ???
readShapeFromFile match {
case Circle(r) => s"It's a circle of radius $r"
case Square(s) => s"It's a square of side $s"
case Rectangle(w, h) => s"It's a rectangle of size $w by $h"
}
// Either
type Error = String
def userId(username: String): Either[Error, Int] =
username match {
case "Noel" => Right(1)
case _ => Left("Bad username")
}
def mostRecentOrderId(userId: Int): Either[Error, Int] =
Right(2)
def orderCost(orderId: Int): Either[Error, Int] =
Right(3)
def mostRecentOrderCost(username: String): Either[Error, Int] =
for {
uid <- userId("Noel").right
oid <- mostRecentOrderId(uid).right
cost <- orderCost(oid).right
} yield cost
// \/
type Error = String
def userId(username: String): Error \/ Int =
username match {
case "Noel" => 1.right
case _ => "Bad username".left
}
def mostRecentOrderId(userId: Int): Error \/ Int =
\/-(2)
def orderCost(orderId: Int): Error \/ Int =
\/-(3)
def mostRecentOrderCost(username: String): Error \/ Int =
for {
uid <- userId("Noel")
oid <- mostRecentOrderId(uid)
cost <- orderCost(oid)
} yield cost
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment