4

I have this piece of code

import scala.util.Try val t: Try[Unit] = Try(Try(1)) 

and 2 questions:

  • What is happening here? How can the type Try[Try[Int]] match with Try[Unit]? Is it because Scala chooses the return type for block Try(1) to be Unit to match with the desired type?
  • Is there anyway to detect a nested Try? Says I have a Try[A], how do I know if A is another Try[_]?
1
  • 1
    If you ask the compiler to discard the value (i.e. type something as Unit explicitly), it will let you do that. stackoverflow.com/a/3513647/14955 Commented Aug 6, 2018 at 3:48

2 Answers 2

7

You are basically forcing compiler to assign Try as Unit.

For exmple doSomething method below is supposed to return Int as that is last statement, but return type Unit is forcing it to return ().

scala> def doSomething: Unit = 1 + 1 doSomething: Unit 

In your example val t: Try[Unit] = Try(Try(1 / 0)), you asking compiler to treat inner Try(1 / 0) as Unit; which means

scala> val innerTry: Unit = Try(1 / 0) innerTry: Unit = () 

Which means even if Try fails, its Unit which is always Success for another Try that you have.

scala> val t: Try[Unit] = Try(someOperation) t: scala.util.Try[Unit] = Success(()) 

Better remove the specific type you are providing and let the compiler figure it out,

scala> val t = Try(Try(1 / 0)) t: scala.util.Try[scala.util.Try[Int]] = Success(Failure(java.lang.ArithmeticException: / by zero)) 

Also read: Scala: Why can I convert Int to Unit?

final abstract class Unit private extends AnyVal { // Provide a more specific return type for Scaladoc override def getClass(): Class[Unit] = ??? } 
Sign up to request clarification or add additional context in comments.

1 Comment

about the 2nd question, how do I prevent this situation to happen? Says if I have a Try[A], how do I know that A is not another Try[_]?
1

Try(1) returns Success(1). Try(Try(1) returns Success(())because of its assignment to Type Try[Unit] Similar to the following commands in Scala REPL where x is forced to take Unit type:

scala> val x = 5 x: Int = 5 scala> val x:Unit = 5 <console>:23: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses val x:Unit = 5 ^ x: Unit = () scala> 

So obviously the compiler is taking the return value and is forced to type () which is Unit. Because it is Unit may be it makes sense the way compiler interprets it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.