2

我在 Scala 编程第 23.5 节中读到,map、flatMap 和 filter 操作总是可以转换为 for-comprehensions,反之亦然。

我们得到以下等价物:

def map[A, B](xs: List[A], f: A => B): List[B] =
  for (x <- xs) yield f(x)

我有一个从一系列地图操作中计算出来的值:

val r = (1 to 100).map{ i => (1 to 100).map{i % _ == 0} }
                  .map{ _.foldLeft(false)(_^_) }
                  .map{ case true => "open"; case _ => "closed" }

我想知道这会是什么样的理解。我该如何翻译它?

(如果它有帮助,用文字来说是:

  • 取 1 到 100 之间的整数
  • 为每个,创建一个包含 100 个布尔值的列表
  • 使用 XOR 运算符折叠每个列表,返回布尔值
  • 根据布尔值产生 100 个字符串“打开”或“关闭”的列表

我想有一种标准的方法来翻译地图操作,其中实际功能的细节并不重要。不过我可能是错的。)

4

1 回答 1

6

这是你要找的翻译吗?

for (i <- 1 to 100;
     val x = (1 to 100).map(i % _ == 0);
     val y = x.foldLeft(false)(_^_);
     val z = y match { case true => "open"; case _ => "closed" })
  yield z

如果需要,map定义中的 thex也可以翻译为“内部”以便理解。

回想起来,一系列链式map调用有点微不足道,因为您可以等效map地使用组合函数调用一次:

 s.map(f).map(g).map(h) == s.map(f andThen g andThen h)

我发现当参与其中时flatMap,理解是一个更大的胜利。filter考虑

for (i <- 1 to 3;
     j <- 1 to 3 if (i + j) % 2 == 0;
     k <- 1 to 3) yield i ^ j ^ k

相对

(1 to 3).flatMap { i =>
  (1 to 3).filter(j => (i + j) % 2 == 0).flatMap { j =>
    (1 to 3).map { k => i ^ j ^ k }
  }
}
于 2011-07-30T04:01:57.983 回答