Try Is Not A Monad

1 minute read

In this blog we will talk about scala.util.Try and try to figure out if it is a Monad.

What is Try?

Try is a data type which can representtry/catch in Scala. As long as you want to catch the exception, you can use it. for example

val a:Try[Int] = Try(1/0)

Let’s see its rough defination

sealed trait Try[+A]
case class Success[+A](value:A) extends Try[A]
case class Failure[+A](exception:Throwable) extends Try[A]

object Try{
    def apply[A](r: =>A):Try[A] = 
      try Sucess(r)
      catch {
        case NonFatal(e) => Failure(e)  
      }
}

We can see the apply of Try is just a syntax sugar of try/catch.

Try also support map and flatMap

$ for {
  	a <- Try(1)
  	b <- Try(2)
  } yield a+b
res1: Try[Int] = Success(3)
$ for {
  	a <- Try(1/0)
  	b <- Try(2)
  } yield a+b
res2: Try[Int] = Failure(java.lang.ArithmeticException: / by zero)

Why Try is not a Monad?

Just like Future, Tryis not referential transparency. Let’s see the following example

$ for {
    _ <- Try(println("hello"))
    _ <- Try(println("hello"))
  } yield ()
hello
hello
res3: Try[Unit] = Success(())
$ val a:Try[Unit] = Try(println("hello"))
hello
a: Try[Unit] = Success(())
$ for {
    _ <- a
    _ <- a
  } yield ()
res5: Try[Unit] = Success(())

These two implementations have different side-effects, one print two hello, the other one just print one hello

Tags:

Updated:

Comments