scala - 用于理解的产量会引发类型不匹配的编译器错误

标签 scala compiler-errors yield type-mismatch for-comprehension

我想从 Iterable[Try[Int]] 中提取所有有效值的列表 (Iterable[Int])

val test = List(
    Try(8), 
    Try(throw new RuntimeException("foo")), 
    Try(42), 
    Try(throw new RuntimeException("bar"))
)

以下是打印 test 中所有有效值的方法:
for {
    n <- test
    p <- n
} println(p)

// Output
// 8
// 42

但是,当我尝试将有效值保存到列表时,我收到了一个错误:
val nums: Seq[Int] = for {
    n <- list
    p <- n    // Type mismatch. Required: IterableOnce[Int], found Try[Int]
} yield(p)
println(nums)

如何修复错误以及为什么会出现错误?

最佳答案

尝试收集

test.collect { case Success(value) => value }
// res0: List[Int] = List(8, 42)

以一种易于理解的格式对应于
for { Success(p) <- test } yield p

两者都使用 Constructor Patterns在引擎盖下执行isInstanceOf类型测试后跟 asInstanceOf类型转换。详细地对应于类似的东西
test
  .filter (_.isInstanceOf[Success[Int]])
  .map    (_.asInstanceOf[Success[Int]].value)

下面的理解不起作用,因为其中的 monads 必须对齐
for {
  n <- test  // List monad
  p <- n     // does not align with Try monad
} yield (p)

上面的理解脱糖
test.flatMap((n: Try[Int]) => n.map((p: Int) => p))

并查看 flatMap 的签名我们看到它需要一个函数
Try[Int] => IterableOnce[Int]

虽然我们提供
Try[Int] => Try[Int]

因为n.map((p: Int) => p)返回 Try[Int] .现在下面的理解是一个完全不同的野兽
for {
    n <- test
    p <- n
} println(p)

因为没有yield它脱糖
test.foreach((n: Try[Int]) => n.foreach((p: Int) => println(p)))

在哪里 foreach需要一个类型的函数
Try[Int] => Unit

我们确实提供了,因为 n.foreach((p: Int) => println(p))确实返回 Unit .

关于scala - 用于理解的产量会引发类型不匹配的编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61763561/

相关文章:

json - Scala 编译器 (2.11.7) 与 Play JSON 写入异常

scala - Scala中自定义组合函数

scala - 如何有条件地调用 sbt 中的任务?

module - 如何包含工作?

visual-c++ - Visual C++不会同时显示两个重新定义错误

c++ - 计算器程序无法编译

java - 增加3个变量

scala - 减少/折叠幺半群列表但减少器返回任一

python - “yield”关键字有什么作用?

Ruby yield 示例解释?