Scala type error with Try [Int]

I have a problem with types that I don't understand. In the code below, I have two methods half1 and half2 that are exactly the same except for half1 . The return type is specified explicitly. However, when I use two methods in foldLeft half , a compiler error occurs. Here is the code. The line setting val c has a problem.

 package org.bodhi.reactive.`try` import scala.util.{Try, Success, Failure} object Hello { def main(args: Array[String]): Unit = { val list = List(1,2,3) Try(1024).flatMap(half1) Try(1024).flatMap(half2) half1(1024).flatMap(half1) half2(1024).flatMap(half2) val a = list.foldLeft(Try(1024))((accum, n) => accum.flatMap(half1)) val b = list.foldLeft(half1(1024))((accum, n) => accum.flatMap(half1)) val c = list.foldLeft(half2(1024))((accum, n) => accum.flatMap(half2)) // Compiler error } def half1(n: Int): Try[Int] = if (n % 2 == 0) Success(n / 2) else Failure(new Exception(s"WRONG $n")) def half2(n: Int) = if (n % 2 == 0) Success(n / 2) else Failure(new Exception(s"WRONG $n")) } 

The error I am getting is:

 [error] /home/chris/projects/reactive/example/src/main/scala/org/bodhi/reactive/try/Hello.scala:18: type mismatch; [error] found : scala.util.Try[Int] [error] required: Product with Serializable with scala.util.Try[Int] [error] val c = list.foldLeft(half2(1024))((accum, n) => accum.flatMap(half2)) 

My question is: why should half1 compiled into foldLeft, but half2 not? I am using scala 2.11.5

+6
source share
1 answer

Both Success and Failure extend Try[T] with Product with Serializable , ( Product with Serializable , because these are case classes). Therefore, when you leave the return type half2 , the return type is displayed as Try[T] with Product with Serializable .

Usually it doesn’t matter, flatMap(half2) will still return Try[T]

 scala> Try(1024).flatMap(half2) res2: scala.util.Try[Int] = Success(512) 

But foldLeft is a completely different story. The problem is that you are passing half(2) as the first argument. Take a look at the signature foldLeft :

 def foldLeft[B](z: B)(op: (A, B) => B): B 

B is inferred from the argument z , which means

 B = Try[T] with Product with Serializable 

This means that op expected to be of type:

 (A, Try[T] with Product with Serializable) => Try[T] with Product with Serializable 

But instead, it is (A, Try[T]) => Try[T] , and this way you get a type mismatch. Using type inference can be nice, but most of the time I explicitly type in return types, you will save a lot of headaches.

+8
source

Source: https://habr.com/ru/post/981809/


All Articles