Skip to content

Instantly share code, notes, and snippets.

@jehrhardt
Created September 22, 2015 08:55
Show Gist options
  • Save jehrhardt/f693fd10683392450c91 to your computer and use it in GitHub Desktop.
Save jehrhardt/f693fd10683392450c91 to your computer and use it in GitHub Desktop.

try

Introduction to Try and IO with Scala.

Repeat Either

Either can be used for errors, but requires convention.

case class BlogNotFoundException(message: String) extends Exception(message)

def byId(id: Int): Blog = {
  require(id > 0, "i must be greater than 1")

  if(id == 1) {
    id
  } else {
    throw BlogNotFoundException(s"Could not find blog with ID $id")
  }
}

val blog: Either[String, Blog] = {
  try {
    Right(byId(2))
  } catch {
    case BlogNotFoundException(message) => Left(message)
  }
}

blog.right.map(i => i * 10)

The convention, that right is the success case can not be checked by the compiler.

The type Try

Use Try instead, for error handling. Try is similar to Option.

val something: Option[String] = Some("something")
val nothing: Option[String] = None

import scala.util.{Failure, Success, Try}

val successful: Try[String] = Success("successful")
val unsuccessful: Try[String] = Failure(new Exception)

Try provides map, flatMap and filter like Option

def foo(text: String): String = text * 2

something.map(foo)
nothing.map(foo)

successful.map(foo)
unsuccessful.map(foo)

def bar(text: String): Option[String] = Some(text * 2)
def tryBar(text: String): Try[String] = Success(text * 2)

something.flatMap(bar)
nothing.flatMap(bar)

successful.flatMap(tryBar)
unsuccessful.flatMap(tryBar)

something.filter(_.length > 20)
successful.filter(_.length > 20)

Thus Try can be used in for comprehensions.

for {
  first <- tryBar("foo")
  second <- tryBar(first)
  third <- tryBar(second)
} yield (first, second, third)

Try provides a recover method

unsuccessful recover {
  case e: IOException => "IO error"
  case _ => "Something went wrong"
}

Reading IO

scala.io provides wrapper around Java IO. Source wraps input collection like.

import scala.io.Source

Source.from("bar")
Source.fromBytes("foo".getBytes)

val file = new File(System.getProperty("user.home") + "/hello.txt")
Source.fromFile(file)

val uri = URI.create("file:///Users/jehrhardt/hello.txt")
Source.fromURI(uri)

The methods have an implicit parameter codec. What is its default?

def currentCodec(implicit codec: Codec) = codec
currentCodec

Ensure the right codec is set:

implicit val codec = Codec.ISO8859
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment