2

私は Scala でのプログラミング セクション 23.5 で、map、flatMap、およびフィルター操作は常に 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て、定義x内の を「内部」の理解用に変換することもできます。

振り返ってみると、一連の連鎖呼び出しは、構成された関数で 1 回map呼び出すことができるという点で、些細なことです。map

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

flatMapfor-comprehensions は、および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 に答える