将选项与列表组合在一起会产生类型不匹配的情况,具体取决于顺序 [英] Composing Option with List in for-comprehension gives type mismatch depending on order
问题描述
为什么这种构造会在Scala中导致类型不匹配错误?
Why does this construction cause a Type Mismatch error in 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,则可以很好地编译:
If I switch the Some with the List it compiles fine:
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)
推荐答案
对于理解,此方法将转换为对 map
或 flatMap
方法的调用.例如,这个:
For comprehensions are converted into calls to the map
or flatMap
method. For example this one:
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
方法调用.由于 List
上的 flatMap
返回另一个 List
,因此for理解的结果当然将是 List
.(这对我来说是新的:因为理解并不总是导致信息流,甚至不一定会导致 Seq
s.)
Therefore, the first loop value (in this case, List(1)
) will receive the flatMap
method call. Since flatMap
on a List
returns another List
, the result of the for comprehension will of course be a List
. (This was new to me: For comprehensions don't always result in streams, not even necessarily in Seq
s.)
现在,看看在 Option
中如何声明 flatMap
:
Now, take a look at how flatMap
is declared in Option
:
def flatMap [B] (f: (A) ⇒ Option[B]) : Option[B]
请记住这一点.让我们看看如何将理解错误(具有 Some(1)
的错误)转换为一系列map调用:
Keep this in mind. Let's see how the erroneous for comprehension (the one with Some(1)
) gets converted to a sequence of map calls:
Some(1).flatMap(x => List(1,2,3).map(y => (x, y)))
现在,很容易看到 flatMap
调用的参数可以返回 List
,而不是 Option
,例如必填.
Now, it's easy to see that the parameter of the flatMap
call is something that returns a List
, but not an Option
, as required.
为了解决问题,您可以执行以下操作:
In order to fix the thing, you can do the following:
for(x <- Some(1).toSeq ; y <- List(1,2,3)) yield (x, y)
这样编译就可以了.值得注意的是, Option
不是通常假定的 Seq
的子类型.
That compiles just fine. It is worth noting that Option
is not a subtype of Seq
, as is often assumed.
这篇关于将选项与列表组合在一起会产生类型不匹配的情况,具体取决于顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!