【问题标题】:"for" translation into lists high order functions"for" 翻译成列表高阶函数
【发布时间】:2014-11-27 01:22:06
【问题描述】:

据我了解,for 表达式被翻译成 Scala 表达式,这些表达式基于:

  • 地图
  • 平面地图
  • 过滤器
  • foreach

高阶列表方法。

一个常见的例子是:

for(b1 <= books; b2 <- books if b1 != b2;
    a1 <- b1.authors; a2 <- b2.authors if a1 == a2) yield a1;

结果:

books flatMap (b1 => 
    books withFilter( b2 => b1 != b2) flatMap( b2 => 
        b1.authors flatMap ( a1 => 
            b2.authors withFilter ( a2 => a2 == a1 ) map ( a2 => a1 )
        )
    )
)

地点:

  • books 是类 Book 对象的列表 (List[Book])
  • Book 具有 authors 类型的公共属性 List[String]

我的问题是关于这一行的:

b2.authors withFilter ( a2 => a2 == a1 ) map ( a2 => a1 )

由于条件为a2 == a1,该行相当于:

b2.authors withFilter ( a2 => a2 == a1 ) map ( x => x )

为什么生成的代码不只是?

b2.authors filter ( a2 => a2 == a1 )

这个例子是不是Scala的编译器自动生成的代码的复现?

filter 不适合“积木”吗?

【问题讨论】:

  • 如果您在上一条语句中将filter 替换为withFilter,我认为两者完全相同,差异可以通过您查看编译器生成的代码来解释。但是,使用 filter 会改变一些事情,它会构造一个新的集合,而不是一个内容被延迟迭代的迭代器。
  • @mrmcgreg 是的,withFilter 会延迟生成它的内容,但是如果你在其上应用带有身份参数化的地图,你会得到与 filter 相同的效果。

标签: scala


【解决方案1】:

for/yield 语法到方法调用的翻译非常简单和机械,几乎在字符串操作的级别。 withFilter 在某些地方因为它的懒惰是必要的,因此为了简单起见,它在任何地方都被使用。我不明白你最后一个问题的措辞,但 for/yield 表达式是 AIUI 从未翻译成对 filter 的调用,除非以不推荐的方式用于尚未具有 withFilter 方法的对象。

【讨论】:

  • 在我的问题结束时我想问的是最后一个map 是否只是为了获得与filter 提供的相同行为。而且,如果是这样的话,我想知道为什么不直接使用filter
猜你喜欢
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多