Pattern Matching
&
Reflection
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)robot.getClass.getMethods .map(_.getName)// res: Array[String] = Array(// "equals",// "toString",// "hashCode",// "position",// "copy",// "direction",// "move",// "productElementNames",// ...
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)robot.getClass.getMethods .map(_.getName)// res: Array[String] = Array(// "equals",// "toString",// "hashCode",// "position",// "copy",// "direction",// "move",// "productElementNames",// ...
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)robot.getClass.getMethods .map(_.getName)// res: Array[String] = Array(// "equals",// "toString",// "hashCode",// "position",// "copy",// "direction",// "move",// "productElementNames",// ...
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)robot.getClass.getMethods .map(_.getName)// res: Array[String] = Array(// "equals",// "toString",// "hashCode",// "position",// "copy",// "direction",// "move",// "productElementNames",// ...
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)robot.getClass.getMethods .map(_.getName)// res: Array[String] = Array(// "equals",// "toString",// "hashCode",// "position",// "copy",// "direction",// "move",// "productElementNames",// ...
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)robot.getClass.getMethods .map(_.getName)// res: Array[String] = Array(// "equals",// "toString",// "hashCode",// "position",// "copy",// "direction",// "move",// "productElementNames",// ...
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)classOf[Robot] .getDeclaredMethod("move") .invoke(robot)// res: Object = Robot(1, Forward)
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)classOf[Robot] .getDeclaredMethod("move") .invoke(robot)// res: Object = Robot(1, Forward)
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)classOf[Robot] .getDeclaredMethod("move") .invoke(robot)// res: Object = Robot(1, Forward)
case class Robot(position: Int, direction: Direction) { def move: Robot = direction match { case Backward => copy(position = position - 1) case Forward => copy(position = position + 1) }}sealed trait Directioncase object Forward extends Directioncase object Backward extends Direction
val robot = Robot(0, Forward)classOf[Robot] .getDeclaredMethod("move") .invoke(robot)// res: Object = Robot(1, Forward)
case class ::[A](val head: A, private var next: List[A]) extends List[A]
case class ::[A](val head: A, private var next: List[A]) extends List[A]
val list = List(1,2,3)// list: List[Int] = List(1, 2, 3)val field = classOf[::[Int]].getDeclaredField("next")field.setAccessible(true)field.set(list, List(4,5,6))list// list: List[Int] = List(1, 4, 5, 6)
val list = List(1,2,3)// list: List[Int] = List(1, 2, 3)val field = classOf[::[Int]].getDeclaredField("next")field.setAccessible(true)field.set(list, List(4,5,6))list// list: List[Int] = List(1, 4, 5, 6)
val list = List(1,2,3)// list: List[Int] = List(1, 2, 3)val field = classOf[::[Int]].getDeclaredField("next")field.setAccessible(true)field.set(list, List(4,5,6))list// list: List[Int] = List(1, 4, 5, 6)
val list = List(1,2,3)// list: List[Int] = List(1, 2, 3)val field = classOf[::[Int]].getDeclaredField("next")field.setAccessible(true)field.set(list, List(4,5,6))list// list: List[Int] = List(1, 4, 5, 6)
val list = List(1,2,3)// list: List[Int] = List(1, 2, 3)val field = classOf[::[Int]].getDeclaredField("next")field.setAccessible(true)field.set(list, List(4,5,6))list// list: List[Int] = List(1, 4, 5, 6)
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = if(value.isInstanceOf[Int]) value.asInstanceOf[Int] + 1 else if(value.isInstanceOf[Double]) value.asInstanceOf[Double] + 1.0 else value
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = if(value.isInstanceOf[Int]) value.asInstanceOf[Int] + 1 else if(value.isInstanceOf[Double]) value.asInstanceOf[Double] + 1.0 else value
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"
def increment(value: Any) = if(value.isInstanceOf[Int]) value.asInstanceOf[Int] + 1 else if(value.isInstanceOf[Double]) value.asInstanceOf[Double] + 1.0 else value
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case x: Option[Int] => x.map(_ + 1) case other => other }
increment(1)// res: Any = 2increment(5.3)// res: Any = 6.3increment("Hello")// res: Any = "Hello"increment(Some(1))// res: Any = Some(2)
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case x: Option[Int] => x.map(_ + 1) case other => other }
increment(Some("Hello"))// java.lang.ClassCastException: class String cannot be cast to class Integer
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case x: Option[Int] => x.map(_ + 1) case other => other }
increment(Some("Hello"))// java.lang.ClassCastException: class String cannot be cast to class Integer
Some("Hello").isInstanceOf[Option[Int]]// res: Boolean = true
trait Auth { def authenticate(token: Token): Future[User]}
trait Auth { def authenticate(token: Token): Future[User]}class OktaAuth(client: RestClient) extends Auth { /* ... */ }class MockAuth(users: Map[Token, User]) extends Auth { /* ... */ }
def checkUser(request: Request, auth: Auth) = request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) }
def checkUser(request: Request, auth: Auth) = request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) }
def checkUser(request: Request, auth: Auth) = request.headers.get("Authorization") match { case None => reject(Forbidden()) // 403 Status case Some(token) => auth.authenticate(token).map(user => provide(user) ) }
def checkUser(request: Request, auth: Auth) = request.headers.get("Authorization") match { case None => reject(Forbidden()) // 403 Status case Some(token) => auth.authenticate(token).map(user => provide(user) ) }
def checkUser(request: Request, auth: Auth) = request.headers.get("Authorization") match { case None => reject(Forbidden()) // 403 Status case Some(token) => auth.authenticate(token).map(user => provide(user) // pass it down the line ) }
def checkUser(request: Request, auth: Auth) = request.headers.get("Authorization") match { case None => reject(Forbidden()) // 403 Status case Some(token) => auth.authenticate(token).map(user => provide(user) // pass it down the line ) }
{ auth : { type : "Okta" baseUrl : "https://okta.com/auth0" api-key : "X28fd-OS0-8S" }}
{ auth : { type : "Mock" users : { "bob" : "abcd" "eda" : "xxxx" } }}
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) } }
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) } }
enum Env { case Local, UAT, Prod}
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) } }
enum Env { case Local, UAT, Prod}
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) } }
enum Env { case Local, UAT, Prod}
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => // same as before request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) } }
enum Env { case Local, UAT, Prod}
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => request.headers.get("Authorization") match { case None => reject(Forbidden()) case Some(token) => auth.authenticate(token).map(user => provide(user) ) } }
class CachedAuth( cache : Cache, underlying: Auth,) extends Auth { /* ... */ }
class CachedAuth( cache : Cache, underlying: Auth,) extends Auth { /* ... */ }
class CachedAuth( cache : Cache, underlying: Auth,) extends Auth { /* ... */ }
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => // check header and dispatch to auth }
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => // check header and dispatch to auth }
val env : Env = Prodval auth: Auth = new CachedAuth(cache, new MockAuth(...))
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => // check header and dispatch to auth }
val env : Env = Prodval auth: Auth = new CachedAuth(cache, new MockAuth(...))
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => // check header and dispatch to auth }
val env : Env = Prodval auth: Auth = new CachedAuth(cache, new MockAuth(...))
def checkUser(request: Request, auth: Auth, env: Env) = (env, auth) match { case (Prod, _: MockAuth) => InternalServerError() case _ => // check header and dispatch to auth }
val env : Env = Prodval auth: Auth = new CachedAuth(cache, new MockAuth(...))
auth match { case _: MockAuth => ... case _ => ...}
env match { case Local => ... case UAT => ... case Prod => ...}
trait Auth { def authenticate(token: Token): Future[Option[User]] // if the token is valid, revoke makes it invalid def revoke(token: Token): Future[Unit]}
trait Auth { def authenticate(token: Token): Future[Option[User]] // if the token is valid, revoke makes it invalid def revoke(token: Token): Future[Unit]}
trait Auth { def authenticate(token: Token): Future[Option[User]] // if the token is valid, revoke makes it invalid def revoke(token: Token): Future[Unit]}
def checkAuth(auth: Auth) = test("revoke makes token invalid") { forAll { (token: Token) => for { _ <- auth.revoke(token) user <- auth.authenticate(token) } assert(user == None) } }
trait Auth { def authenticate(token: Token): Future[Option[User]] // if the token is valid, revoke makes it invalid def revoke(token: Token): Future[Unit]}
def checkAuth(auth: Auth) = test("revoke makes token invalid") { forAll { (token: Token) => for { _ <- auth.revoke(token) user <- auth.authenticate(token) } assert(user == None) } }
trait Auth { def authenticate(token: Token): Future[Option[User]] // if the token is valid, revoke makes it invalid def revoke(token: Token): Future[Unit]}
def checkAuth(auth: Auth) = test("revoke makes token invalid") { forAll { (token: Token) => for { _ <- auth.revoke(token) user <- auth.authenticate(token) } assert(user == None) } }
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }// warning pattern selector should be an instance of// Matchable, but it has unmatchable type Any instead
def increment(value: Any) = value match { case x: Int => x + 1 case x: Double => x + 1.0 case other => other }// warning pattern selector should be an instance of// Matchable, but it has unmatchable type Any instead
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |