简体   繁体   English

流中的类型推断

[英]Type Inference in Stream

Why can't the compiler infer the type of the wildcard in the filter ? 为何编译器无法在filter器中推断通配符的类型?

scala> Stream.from(1) takeWhile(_ < 1000) filter ( ( _ % 3  == 0) || ( _ % 5 == 0)) sum

<console>:18: error: missing parameter type for expanded function ((x$2) => x$2.$percent(3).$eq$eq(0))
              Stream.from(1) takeWhile(_ < 1000) filter ( ( _ % 3  == 0) || ( _ % 5 == 0)) sum

This works fine: 这很好用:

scala> Stream.from(1).takeWhile( x => x < 1000).filter(x => (x % 3 == 0) || (x % 5 == 0)).sum

From the SLS 6.23.1 : SLS 6.23.1开始

If an expression e binds underscore sections u1,…,un , in this order, it is equivalent to the anonymous function (u′1, ... u′n) => e′ where each u′i results from ui by replacing the underscore with a fresh identifier and e′ results from e by replacing each underscore section ui by u′i . 如果表达式e按此顺序绑定下划线部分u1,…,un ,则等效于匿名函数(u′1, ... u′n) => e′ ,其中每个u′iui替换而来用新鲜的标识符和下划线e′从结果e通过替换各个强调部uiu′i

This means that multiple underscores using the placeholder syntax imply an anonymous function with multiple parameters. 这意味着使用占位符语法的多个下划线表示具有多个参数的匿名函数。

ie

(_ > 0) expands to (x => x > 0) (_ > 0)扩展为(x => x > 0)

(_ > 0 || _ < -10) expands to ((x, y) => x > 0 || y < -10) (_ > 0 || _ < -10)扩展为((x, y) => x > 0 || y < -10)

(_ > 0 || _ < -10 || _ % 2 == 0) expands to ((x, y, z) => x > 0 || y < -10 || z % 2 == 0) (_ > 0 || _ < -10 || _ % 2 == 0)扩展为((x, y, z) => x > 0 || y < -10 || z % 2 == 0)

And so on.. The error is a little confusing because it looks like it's trying to read it as an arity-1 function within each set of parenthesis based on the error message. 等等。该错误有点令人困惑,因为它似乎正在尝试根据错误消息将其读取为每套括号内的arity-1函数。 I'll speculate that it then doesn't know what to do with the expression x => a || y => b 推测它不知道如何处理表达式x => a || y => b x => a || y => b to infer the types to somehow come up with Int => Boolean . x => a || y => b推断类型,以某种方式得出Int => Boolean

Each subsequent instance of _ refers to the next argument. _每个后续实例都引用下一个参数。 If you want to reuse an argument of a lambda, you must name it like you did in the 2nd version you posted. 如果要重用lambda的参数,则必须像在发布的第二版中一样命名。

The first version desugared would be more like 废止的第一个版本更像

filter ((x,y) => ( x % 3 == 0) || ( y % 5 == 0))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM