gpt4 book ai didi

scala - 为什么我不能 flatMap a Try?

转载 作者:行者123 更新时间:2023-12-03 23:32:03 24 4
gpt4 key购买 nike

给定的

val strings = Set("Hi", "there", "friend")
def numberOfCharsDiv2(s: String) = scala.util.Try {
if (s.length % 2 == 0) s.length / 2 else throw new RuntimeException("grr")
}

为什么我不能 flatMap 远离方法调用产生的 Try? IE。
strings.flatMap(numberOfCharsDiv2)
<console>:10: error: type mismatch;
found : scala.util.Try[Int]
required: scala.collection.GenTraversableOnce[?]
strings.flatMap(numberOfCharsDiv2)

要么
for {
s <- strings
n <- numberOfCharsDiv2(s)
} yield n
<console>:12: error: type mismatch;
found : scala.util.Try[Int]
required: scala.collection.GenTraversableOnce[?]
n <- numberOfCharsDiv2(s)

但是,如果我使用 Option 而不是 Try 则没有问题。
def numberOfCharsDiv2(s: String) = if (s.length % 2 == 0) 
Some(s.length / 2) else None
strings.flatMap(numberOfCharsDiv2) # => Set(1, 3)

不允许在 Try 上使用 flatMap 的原因是什么?

最佳答案

我们来看看flatMap的签名.

def flatMap[B](f: (A) => GenTraversableOnce[B]): Set[B]

您的 numberOfCharsDiv2被视为 String => Try[Int] . Try不是 GenTraversableOnce 的子类这就是为什么你会得到错误。你并不严格需要一个给出 Set 的函数只因为你使用 flatMapSet .该函数基本上必须返回任何类型的集合。

那么为什么它适用于 Option ? Option也不是 GenTraversableOnce 的子类,但 Option 内部存在隐式转换伴随对象,将其转换为 List .
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList

那么还有一个问题。为什么不对 Try 进行隐式转换还有吗?因为你可能得不到你想要的。
flatMap可以看作是 map后跟一个 flatten .

假设你有一个 List[Option[Int]]喜欢 List(Some(1), None, Some(2)) .然后 flatten会给你 List(1,2)类型 List[Int] .

现在看一个 Try 的例子. List(Success(1), Failure(exception), Success(2))类型 List[Try[Int]] .

现在扁平化将如何与失败一起工作?
  • 它应该像None一样消失吗? ?那么为什么不直接使用 Option ?
  • 它应该包含在结果中吗?然后就是 List(1, exception, 2) .这里的问题是类型是 List[Any] ,因为你必须为 Int 找到一个共同的父类(super class)和 Throwable .你失去了类型。

  • 这些应该是没有隐式转换的原因。当然,如果您接受上述后果,您可以自己定义一个。

    关于scala - 为什么我不能 flatMap a Try?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25583368/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com