import scala.io.Source def readFile(path: String) = (Source fromFile path).mkString()
import java.io.IOException try { readFile("/opt/data") } catch { case e: IOException => }
import java.lang.NumberFormatException try { readFile("/opt/social-security").toInt } catch { case e @ (_: IOException | _: NumberFormatException) => }
import java.nio.file.{ Files, FileSystemException, FileSystems } try { val path = FileSystems.getDefault getPath "/opt/data" Files readAllBytes path } catch { // abstracting over: // - java.nio.file.NoSuchFileExceptions // - java.nio.file.NotDirectoryException // - all other subclasses case e: FileSystemException => }
try { readFile("/opt/data").toInt } catch { case e: IOException if e.getMessage contains "Is a directory" => case e: IOException => }
try { readFile("/opt/data").toInt } catch { case e: Exception => }
try { readFile("/opt/data").toInt } catch { // this will match scala.util.control.ControlThrowable case _ => }
try { readFile("/opt/data").toInt } catch { case t: ControlThrowable => throw t case _ => }
val a1: Nothing = sys error "foo"
sealed trait Try[A] case class Failure[A](e: Throwable) extends Try[A] case class Success[A](value: A) extends Try[A]
import scala.util.Try def tryReadFile(path: String): Try[String] = Try { (Source fromFile path).mkString() }
import scala.util.control._ import scala.util.control.Exception._ tryReadFile("/opt/data") match { case Success(value) => case Failure(e) => }
val c: Catch[A] = catching(classOf[IOException])
val sOpt: Option[String] = catching(classOf[IOException]).opt { readFile("/opt/data") }
val sOpt: Option[String] = failing(classOf[IOException]) { readFile("/opt/data") }
val eith: Either[Throwable, String] = catching(classOf[IOException]).either { readFile("/opt/data") }
val unit: Unit = ignoring(classOf[IOException], classOf[NumberFormatException]) { println(readFile("/opt/social-security").toInt) }
allCatch { readFile("/opt/data") }
nonFatal { readFile("/opt/data") }
try { readFile("/opt/data") } catch { case NonFatal(e) => }
failAsValue(classOf[IOException])("") { readFile("/opt/data") }
def logError(t: Throwable): Int = { println("Error: " + t) -1 } def loggingExceptions(block: => A) = catching(classOf[Exception]).withApply { logError _ }.apply(block)
catching(classOf[IOException]).andFinally { println("cleanup") }.apply { readFile("/opt/data") }
ultimately(println("cleanup")) { readFile("/opt/data") }
sealed trait Option[A] case class Some[A](a: A) extends Option[A] case object None extends Option[Nothing]
val iOpt: Option[Int] = //... val sOpt: Option[String] = iOpt match { case Some(value) => value.toString case None => "" }
val sOpt: Option[String] = iOpt map { value => value.toString } val sOpt: Option[String] = iOpt map { _.toString }
def foo(i: Int): Option[String] val sOpt: Option[String] = foo(1).orElse { foo(2).orElse { foo(3).orElse { foo(4) } } }
val sOpt: Option[String] = iOpt.fold("") { _.toString }
val i: Int = iOpt getOrElse 0
import scala.math.sqrt def perfectSqrt(i: Int): Option[Int] = { val root: Int = sqrt(i).toInt if (root * root == i) Some(root) else None } val i: Int = //... perfectSqrt(i).flatMap { perfectSqrt(_).flatMap { perfectSqrt(_) } }
def triplePerfectSqrt(i: Int): Option[Int] = for { j <- perfectSqrt(i) k <- perfectSqrt(j) l <- perfectSqrt(k) } yield l
val b1: Boolean = iOpt.isDefined val b2: Boolean = iOpt.isEmpty
val b1: Boolean = iOpt exists { _ > 0 }
//MAY RETURN NULL def javaFunction(): String val sOpt: Option[String] = Option(javaFunction())
val iOpt: Option[Int] = //... val cOpt: Option[Char] = //... val dOpt: Option[Double] = //... val sOpt: Option[String] = for { i <- iOpt c <- cOpt d <- dOpt } yield s"$i$s$d"
sealed trait Either[E, A] case class Left[E](e: E) extends Either[E, A] case class Right[A](a: A) extends Either[E, A]
val eith: Either[Int, String] = //... eith match { case Left(e) => case Right(value) => }
eith.fold( _.toString, _.reverse )
def div(i: Int, j: Int): Either[String, Int] = if (j != 0) Right(i / j) else Left(s"can't divide $i by 0!") val i, j, k, l, m, n = // ... integers for { i <- div(j, k).right l <- div(m, n).right } yield i + l
for { i <- div(j, k).left l <- div(m, n).left } yield i + l
sealed trait Validation[E, A] case class Success[E, A](a: A) extends Validation[E, A] case class Failure[E, A](e: E) extends Validation[E, A]
case class NonEmptyList[A](head: A, tail: List[A]) type ValidationNEL[E, A] = Validation[NonEmptyList[E], A]
class Person( age: Int, clothes: String, sober: Boolean, male: Boolean ) def checkAge(p: Person): Validation[String, Person] = if (p.age < 18) Failure("too young!") else Success(p) def checkClothes(p: Person): Validation[String, Person] = if (p.clothes contains "jeans") Failure("dress up!") else Success(p) def checkSobriety(p: Person): Validation[String, Person] = if (p.sober) Success(p) else Failure("sober up!")
def cost(p: Person): ValidationNEL[String, Int] = ( checkAge(p).liftFailNel |@| checkClothes(p).liftFailNel |@| checkSobriety(p).liftFailNel) { case (_, _, c) => if (c.male) 50 else 25 }
trait Duck { def quack(): Unit } def foo(d: Duck) =
def foo(d: { def quack(): Unit }) =
trait Monad[M[_]]
class OptionMonad[A] extends Monad[Option]
class EitherMonad[A] extends Monad[Either]
class EitherMonad[A] extends Monad[Either[E]]
//recall our definition of Monad trait Monad[M[_]] //solution class EitherMonad[A] extends Monad[({type λ[α] = Either[A, α]})#λ]
{ }
{ type L[A] = Either[E, A] }
{ type L[A] = Either[E, A] }#L
{ type λ[α] = Either[E, α] }#λ
trait Monad[M[_]] class EitherMonad[A] extends Monad[({type λ[α] = Either[A, α]})#λ]
def cost(p : Person) : ValidationNEL[String, Int] = { val checks = List( checkAge _, checkClothes _, checkSobriety _ ) checks.traverse[({type λ[α] = ValidationNEL[String, α]})#λ, Person]( _ andThen (_.liftFailNel) apply p ) map { case c :: _ => if (c.male) 50 else 25 } }
sealed trait Box[A] case class Full[A](a: A) extends Box[A] abstract class EmptyBox extends Box[Nothing] case class Failure( msg: String, e: Box[Throwable], chain: Box[Failure] ) extends EmptyBox case class Empty extends EmptyBox
/
#