猿问

Scala上的类型不匹配以进行理解

为什么这种构造会在Scala中导致类型不匹配错误?


for (first <- Some(1); second <- List(1,2,3)) yield (first,second)


<console>:6: error: type mismatch;

 found   : List[(Int, Int)]

 required: Option[?]

       for (first <- Some(1); second <- List(1,2,3)) yield (first,second)

如果我用列表切换Some,它可以很好地编译:


for (first <- List(1,2,3); second <- Some(1)) yield (first,second)

res41: List[(Int, Int)] = List((1,1), (2,1), (3,1))

这也可以正常工作:


for (first <- Some(1); second <- Some(2)) yield (first,second)


墨色风雨
浏览 588回答 3
3回答

摇曳的蔷薇

对于理解将转换为对mapor flatMap方法的调用。例如这个:for(x <- List(1) ; y <- List(1,2,3)) yield (x,y)变成:List(1).flatMap(x => List(1,2,3).map(y => (x,y)))因此,第一个循环值(在本例中为List(1))将接收flatMap方法调用。由于flatMap在List返回另一个List,的的理解,结果当然会是一个List。(这对我来说是新的:因为理解并不总是导致信息流,甚至不一定会导致Seqs。)现在,看看如何flatMap在中声明Option:def flatMap [B] (f: (A) ⇒ Option[B]) : Option[B]请记住这一点。让我们看看如何将理解错误(带有的错误Some(1))转换为一系列map调用:Some(1).flatMap(x => List(1,2,3).map(y => (x, y)))现在,很容易看到该flatMap调用的参数是按要求返回a List而不是返回的东西Option。为了解决问题,您可以执行以下操作:for(x <- Some(1).toSeq ; y <- List(1,2,3)) yield (x, y)这样编译就可以了。值得注意的是,Option它不是Seq通常所假定的的子类型。

慕尼黑8549860

一个容易记住的技巧,因为理解会尝试返回第一个生成器的集合类型,在这种情况下为Option [Int]。因此,如果从Some(1)开始,则应该期望Option [T]的结果。如果要获取列表类型的结果,则应从列表生成器开始。为什么有此限制,而不假定您总是需要某种顺序?您可能会遇到需要返回的情况Option。也许你有一个Option[Int]你想要的东西结合起来,得到一个Option[List[Int]],用下面的函数说:(i:Int) => if (i > 0) List.range(0, i) else None; 然后,您可以编写此代码,并在事情没有“意义”时得到None:val f = (i:Int) => if (i > 0) Some(List.range(0, i)) else Nonefor (i <- Some(5); j <- f(i)) yield j// returns: Option[List[Int]] = Some(List(0, 1, 2, 3, 4))for (i <- None; j <- f(i)) yield j// returns: Option[List[Int]] = Nonefor (i <- Some(-3); j <- f(i)) yield j// returns:&nbsp; Option[List[Int]] = None实际上,如何扩展理解力实际上是将类型的对象M[T]与函数组合(T) => M[U]以获得类型的对象的相当通用的机制M[U]。在您的示例中,M可以是Option或List。通常,它必须是相同的类型M。因此,您不能将Option与List结合使用。有关可能存在的其他情况的示例M,请查看此特征的子类。为什么结合List[T]与(T) => Option[T]工作虽然当你开始与列表?在这种情况下,库在有意义的地方使用更通用的类型。因此,您可以将List与Traversable结合使用,并且存在从Option到Traversable的隐式转换。底线是:考虑要让表达式返回哪种类型,并以该类型作为第一个生成器开始。如有必要,将其包装为该类型。
随时随地看视频慕课网APP
我要回答