Functional Python Programming という本を読んでいたら、 Wrap-Unwrap Pattern というものを知ったので、ちょっとメモ.
https://www.amazon.com/Functional-Python-Programming-Expressive-Implementations-ebook/dp/B00T96XC0Q
公式
unwrap(process(wrap(iterable)))
- wrap() ラッパー
- unwrap() アンラッパー ラッパーで処理したものをもとに戻す.
- process() 処理したい手続き
- iterable 処理したいデータ
ラッパーは、iterable なデータをタプルに加工する. タプルを利用するのは、タプルが immutable なデータ構造だから.
例: 最大値を求める
以下、python による例です.
以下のデータ構造で身長が最大の人を調べる.
- 太郎: 170
- 次郎: 160
- 三郎: 180
students = [("Taro", 170), ("Jiro", 160), ("Saburo", 180)]
max 関数は、そのままでは利用できない.
>>> max(students)
('Taro', 170)
ラッパーでタプルを作成する. wrap 関数は、generator expression ともいう.
def wrap(students):
return ((student[1], student) for student in students)
def unwrap(data):
length, student = data
return student
パターンを適用.
unwrap(max(wrap(students)))
>>> unwrap(max(wrap(students)))
('Saburo', 180)
その他
wrap 関数をいちいち定義するのは面倒なので、lambda が利用される.
>>> max(map(lambda s: (s[1], s), students))[1]
('Saburo', 180)
map を利用する場合の方が、generator expression よりも、高速らしい.
unwrap の操作でタプルの一番目、二番目を取り出すのは常套手段. なので、Haskell には、fst,snd という関数が用意されている.
- fst: タプルの 1 番目の要素を取り出し
- snd: タプルの 2 番目の要素を取り出し