什么时候进行类型检查以进行理解?
When is type checking done in for comprehension?
关于使用 map
、flatMap
和 withFilter
对 for
表达式进行脱糖的主题,Programming In Scala 3rd Ed 一书 说(在“重新访问表达式”一章中)
The translation of for
expressions happens before type checking. This allows for maximum flexibility because the only requirement is that the result of expanding a for
expression type checks.
但是,在 REPL 中,
for (x: Int <- List("a", "b")) yield x
给予
<console>:12: error: scrutinee is incompatible with pattern type;
found : Int
required: String
for(x: Int <- List("a", "b")) yield x
^
同样,
for(x <- List("a", "b")) yield math.pow(x, 2)
给予
<console>:12: error: type mismatch;
found : String
required: Double
for(x <- List("a", "b")) yield math.pow(x, 2)
^
在我看来,这似乎与书中的内容相矛盾,因为它似乎在脱糖之前进行了类型检查。也许...
- 我对这本书的理解有误,请指教-特别是脱糖前后检查的类型是什么?
- 编译器类型检查生成的映射,发现不一致,然后根据 for 表达式记录问题以便于调试
我相信你的第二个建议是正确的。这两种类型的错误都发生在翻译之后,但是如果编译器在给您错误时将您指向某些生成的代码,那将是非常烦人的。想象一下它给出了这条消息:
<console>:12: error: type mismatch;
found : String
required: Double
List("a", "b").map(x => math.pow(x, 2))
^
然后你必须坐在那里思考这段代码是什么——你没有编写任何对 map
的调用或任何类似的匿名函数。如果 for-comprehension 更复杂,情况会更糟 10 倍,并导致多个嵌套的 flatMap
s 和 withFilter
s 等等。因此,它会将您指向您实际编写的预转换版本。
关于使用 map
、flatMap
和 withFilter
对 for
表达式进行脱糖的主题,Programming In Scala 3rd Ed 一书 说(在“重新访问表达式”一章中)
The translation of
for
expressions happens before type checking. This allows for maximum flexibility because the only requirement is that the result of expanding afor
expression type checks.
但是,在 REPL 中,
for (x: Int <- List("a", "b")) yield x
给予
<console>:12: error: scrutinee is incompatible with pattern type;
found : Int
required: String
for(x: Int <- List("a", "b")) yield x
^
同样,
for(x <- List("a", "b")) yield math.pow(x, 2)
给予
<console>:12: error: type mismatch;
found : String
required: Double
for(x <- List("a", "b")) yield math.pow(x, 2)
^
在我看来,这似乎与书中的内容相矛盾,因为它似乎在脱糖之前进行了类型检查。也许...
- 我对这本书的理解有误,请指教-特别是脱糖前后检查的类型是什么?
- 编译器类型检查生成的映射,发现不一致,然后根据 for 表达式记录问题以便于调试
我相信你的第二个建议是正确的。这两种类型的错误都发生在翻译之后,但是如果编译器在给您错误时将您指向某些生成的代码,那将是非常烦人的。想象一下它给出了这条消息:
<console>:12: error: type mismatch;
found : String
required: Double
List("a", "b").map(x => math.pow(x, 2))
^
然后你必须坐在那里思考这段代码是什么——你没有编写任何对 map
的调用或任何类似的匿名函数。如果 for-comprehension 更复杂,情况会更糟 10 倍,并导致多个嵌套的 flatMap
s 和 withFilter
s 等等。因此,它会将您指向您实际编写的预转换版本。