类型不匹配在斯卡拉理解 [英] Type Mismatch on Scala For Comprehension

查看:201
本文介绍了类型不匹配在斯卡拉理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么这个构造在Scala中导致类型不匹配错误?(b)第二个< - 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)

如果我用List切换Some, (第一个< - 列表(1,2,3);第二个< - 一些(1))yield(第一个,第二个)
res41:List [(Int,Int)] = List((1,1),(2,1),(3,1))

这也可以正常工作:

  for(first< ;一些(1);第二个<  - 一些(2))收益(第一,第二)


解决方案

理解转换为对 map flatMap 方法的调用。例如这个:
$ b $ pre $ 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) code>)将会收到 flatMap 方法调用。在 List > > List > List 上返回 flatMap ,结果的理解当然是 List 。 (这对我来说是新的:理解并不总是导致流,甚至不一定在 Seq s。)



现在,看看如何在 Option 中声明 flatMap

  def flatMap [B](f:(A)⇒选项[B]):选项[B] 

记住这一点。让我们来看看错误的理解( Some(1))被转换为一系列map调用:



(1).flatMap(x => List(1,2,3).map(y =>(x,y)))

现在很容易看到 flatMap 调用的参数是根据需要返回 List ,但不是 Option 的东西。



为了解决这个问题,您可以执行以下操作:

  for(x < - (1).toSeq; y<  -  List(1,2,3))yield(x,y)

编译得很好。值得注意的是, Option 不是 Seq 的子类型,正如通常所假设的那样。 $ b

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)

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))

This also works fine:

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

解决方案

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)

becomes that:

List(1).flatMap(x => List(1,2,3).map(y => (x,y)))

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 Seqs.)

Now, take a look at how flatMap is declared in Option:

def flatMap [B] (f: (A) ⇒ Option[B]) : Option[B]

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)))

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)

That compiles just fine. It is worth noting that Option is not a subtype of Seq, as is often assumed.

这篇关于类型不匹配在斯卡拉理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆