Sequence Abstractions in Clojure
上記のリンクはClojureのシーケンスに関する記事なのですが、”Difficult Sequences”のところが面白かったのでメモします。
Clojureでは、map
、filter
を始めとした豊富なシーケンス用関数がありますが、例えば「1つ前の要素を参照する」処理はどう書くのでしょうか。
手続き型言語では、以下のように記述できます。
1 2 3 4 |
|
この「1つ前の要素を参照する」処理をシーケンスで実現するために、まず「1つずらしたシーケンス」を考えてみます。
1 2 |
|
すると、上下が重なっている部分が、「1つ前の要素」と「現在の要素」の組み合わせになっています。
Clojureのmap関数では、復数のシーケンスを同時に扱うことができます。
1 2 |
|
渡したシーケンスの最初の要素同士、2番目の要素同士、がそれぞれ”+”されています。
「元のシーケンス」、「1つずらしたシーケンス」、を用意してmap関数に渡してやれば、目的の処理が実現できそうです。
「1つずらしたシーケンス」を得るには、rest
関数が利用できます。
1 2 3 |
|
rest関数が返すのは、シーケンスの先頭以外を含むシーケンスです。
これらを組み合わせると目的の処理を実現できます。
1 2 |
|
ここでは
1 2 |
|
上記2つのシーケンスの重なっている要素同士の足し算”+”が行われ、目的が実現できています。
map
関数に長さの異なるシーケンスを渡された場合、長いシーケンスの余り部分は無視されます。