Scala中具有理解力的补救语法问题 [英] Remedial syntax issue with for-comprehension in Scala

查看:66
本文介绍了Scala中具有理解力的补救语法问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Scala 2.10中遇到了语法理解方面的问题.

I'm having syntax issues with a for-comprehension in Scala 2.10.

for(a <- List(Some(1,2)); b <- a) yield b的计算结果为List(1,2)

那么为什么for(a <- Some(List(1,2)); b <- a) yield b不能评估相同的东西?

so why doesn't for(a <- Some(List(1,2)); b <- a) yield b evaluate to the same thing?

类型检查器抱怨第二个表达式(b <-a)说找到了List[Int] 当期望Option[?]

The type-checker complains about the second expression (b <-a) saying it found a List[Int] when expecting an Option[?]

推荐答案

我最近已经对此进行了解释-希望有人可以找到该链接.这是一个反复出现的问题,因此很可能已经解决.

I've explained this very recently -- hopefully someone can find the link. It's a recurring question, so it may well be closed.

无论如何,外部生成器控制表示.这发生在每个级别,所以如果我有这个:

At any rate, the outer generator controls the representation. That happens on each level, so if I have this:

for { 
  a <- A
  b <- B
  c <- C
} yield f(a, b, c)

然后,f(a, b, c)的表示形式由C控制,其表示形式由B控制,最终结果的表示形式由A控制.因此,出于大多数实际目的,用于理解的表示形式是由第一生成器控制的.

Then the representation of f(a, b, c) is controlled by C, the representation of that is controlled by B, and the representation of the final result is controlled by A. So, for most practical purposes, the representation of the for comprehension is controlled by the first generator.

那么代表"是什么意思?好吧,通常,对于for的理解是单子理解(实际上,它只是对flatMapmap之类的方法的一组调用,因此可以进行类型检查的任何 ).这意味着给定一个monad M[A]和一个函数A => M[B],然后您可以在M[B]中转换M[A],其中M是monad,是表示形式".

So what do I mean by "representation"? Well, a for comprehension is a monadic comprehension, usually (actually, it's just a set of calls to methods like flatMap and map, so it can be anything that typechecks). That means that given a monad M[A] and a function A => M[B], then you can transform M[A] in M[B], where M, the monad, is the "representation".

这意味着,在大多数情况下,将OptionList组合在一起以理解是不可能的.所有集合在GenTraversableOnce中都有一个共同的父代,因此合并它们没有问题(尽管事情比幕后要复杂得多).

This means that, for the most part, it would be impossible to combine Option and List in a for comprehension. All the collections have a common parent in GenTraversableOnce, so there's no problem in combining them (though things are much more complicated than that under the hood).

但是,存在从OptionIterable的隐式转换.就是这种情况,当Scala在第一个示例中找到b <- a时,并且由于理解是受List的控制而知道它不能通过Option时,它将把Option转换为Iterable,一切正常.

However, there is an implicit conversion from Option to Iterable. That being the case, when Scala finds b <- a in the first example, and knowing it can't pass an Option because the comprehension is being "controlled" by a List, it converts the Option into an Iterable, and everything works.

但是,在第二种情况下不会发生这种情况.用Option进行理解是可以的,因此无需将其转换为Iterable.不幸的是,不能将List转换为Option(这种转换的结果是什么?),所以会导致错误.

However, that doesn't happen in the second case. Doing a for comprehension with an Option is ok, so there's no need to convert it into an Iterable. Unfortunately, one cannot convert a List into an Option (what would be the result of such a conversion?), which results in the error.

Scala不会回溯"到a <- Some(List(1, 2))并对其进行隐式转换,因为Scala中的类型推断只会继续进行-之前决定的内容将保持不变.

Scala will not "backtrack" to a <- Some(List(1, 2)) and apply an implicit conversion to it, as type inference in Scala only goes forward -- what it decided before will remain as is.

我衷心推荐您查看相关问题,并了解a for comprehension的翻译方式.

I heartily recommend you look at the related questions and understand how a for comprehension is translated.

这篇关于Scala中具有理解力的补救语法问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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