我有类型的问题,我不明白.在下面的代码中,我有两个方法half1,half2它们完全相同,只是half1显式指定了返回类型.然而,当我在foldLeft中使用这两个方法时half会导致编译器错误.这是代码.设置的行val c有问题.
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"))
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
[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))
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么在half1foldLeft中使用comile,但half2不是?我正在使用scala 2.11.5
无论Success和Failure扩展Try[T] with Product with Serializable,(Product with Serializable因为他们是case类).因此,当您将返回类型保留为off时half2,返回的类型将被推断为Try[T] with Product with Serializable.
通常这没关系,flatMap(half2)仍会返回Try[T]
scala> Try(1024).flatMap(half2)
res2: scala.util.Try[Int] = Success(512)
Run Code Online (Sandbox Code Playgroud)
但这foldLeft是一个不同的故事.问题是当你half(2)作为第一个参数传递时.让我们来看看签名foldLeft:
def foldLeft[B](z: B)(op: (A, B) => B): B
Run Code Online (Sandbox Code Playgroud)
B从论证中推断出z,这意味着
B = Try[T] with Product with Serializable
Run Code Online (Sandbox Code Playgroud)
这意味着op预计会有这样的类型:
(A, Try[T] with Product with Serializable) => Try[T] with Product with Serializable
Run Code Online (Sandbox Code Playgroud)
但相反,它会(A, Try[T]) => Try[T]导致类型不匹配.使用类型推断可能很好,但大多数时候显式键入返回类型将为您节省很多麻烦.