2012年7月31日火曜日

クラウド温泉3.0 (10) / map, filter, fold

クラウド温泉3.0@小樽のセッション「Monadicプログラミング・マニアックス」で使用するスライドのネタ検討その10です。

パイプライン・プログラミングを構成する要素として以下の2つを説明しました。

Functorが提供する計算文脈におけるパイプラインでは、一般的にmapメソッドに加えてfilterメソッドとfoldメソッドを使うことができます。たとえばListでは以下のようになります。

scala> List(1, 2, 3).filter(_ % 2 == 1).map(_ * 2).fold(0)(_ + _)
res3: Int = 8

このようにメソッドをつないでパイプラインを構築することができるわけです。map, filter, foldメソッドは基本中の基本部品となっています。

for式

mapメソッドとfilterメソッドはfor式の文法糖衣も用意されています。文法糖衣が用意されていることからも基本中の基本であることがわかります。

上記の式の前半は以下になります。

scala> List(1, 2, 3).filter(_ % 2 == 1).map(_ * 2)
res5: List[Int] = List(2, 6)

これはfor式を使って以下のように書くことができます。

scala> for (x <- List(1, 2, 3) if x % 2 == 1) yield x
res4: List[Int] = List(1, 3)

パイプラインの構成部品

map, filter, foldメソッドをパイプラインの構成部品と考えて、パイプラインの観点から整理してみました。

メソッド動作動作イメージコンテナ要素要素数
mapコンテナ上の要素に関数を適用して新しいコンテナに詰め直す。M[A]→M[B]変わらない変わる変わらない
filterコンテナ上の要素を選別して新しコンテナに詰め直す。M[A]→M[A]変わらない変わる減る
foldコンテナをまるごと別のオブジェクトに変換する。M[A]→N変わるなくなるなくなる

説明の都合上コンテナという用語を導入しました。コンテナは計算文脈の実装と考えてもよいですし、パイプライン上に要素を載せて流れる荷車というようにイメージしてもよいでしょう。

このように整理することでパイプラインの構成部品を分類するための軸として以下のものを抽出することができました。

  • コンテナの型の変換 (選択肢: 変わる、変わらない)
  • 要素の型の変換 (選択肢: 変わる, なくなる)
  • 要素数の変化 (選択肢: 変わらない, 減る, なくなる)

バリエーションの組み合わせ的にはmap, filter, foldの3種類以外にも色々と有用な組み合わせがありそうです。

fold

foldメソッドは、コンテナをまるごと別のオブジェクトに変換するので、パイプラインの終端ということになります。

foldメソッドは色々なバリエーションがあります。以下の記事が参考になると思います。

0 件のコメント:

コメントを投稿