From: Yukihiro Matsumoto Date: 2010-03-14T07:30:51+09:00 Subject: [ruby-dev:40632] Re: Enumerable#interleave まつもと ゆきひろです In message "Re: [ruby-dev:40628] Re: Enumerable#interleave" on Sun, 14 Mar 2010 01:11:20 +0900, Tanaka Akira writes: |Clojure にいろいろとある機能のうち、interleave に注目した理由が |きっとあるはずで、それを書けばいいと思うんですが難しいですかね。 | |もちろん提案者以外のひとがユースケースを提供してもいいんですが、 |私にはちょっと想像力が及びませんでした。 | |想像力の代わりに検索力を使うと、 |Clojure の interleave の説明にはユースケースは書いてないようです。 |http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/interleave ありませんね。 |Haskell にあるという定義は見つかりませんでした。 |どこにあるんでしょう? ちょっと調べてみたのですが、Haskellに組み込みであるのではな いようです。が、permutationの定義に(自前で定義して)使われて いるようです。 -- permutations xs returns the list of all permutations of xs. -- e.g., permutations "abc" == ["abc","bac","bca","acb","cab","cba"] permutations :: [a] -> [[a]] permutations [] = [[]] permutations (x:xs) = [zs | ys <- permutations xs, zs <- interleave x ys ] where interleave :: a -> [a] -> [[a]] interleave x [] = [[x]] interleave x (y:ys) = [x:y:ys] ++ map (y:) (interleave x ys) はからずもinterleaveのユースケースになってるのかもしれません。 |さらに検索していくと、join を一般化したような話ですかねぇ。 |http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started |の (interleave completions (repeat "\n")) とか。 | |それなら join を使えよ、という気もしますが、join と比較すると |* 最後の要素の終わりにもつけられる |* 区切りを複数種にできる |* 文字列以外にも使える |というあたりが利点になるでしょうか。 あと、joinはくっつけて文字列にしてしまうので、それがうれしい 時と、うれしくない時があるでしょうね。 |さらに思ったんですが、 |interleave の引数に cycle 等の無限リスト、あるいはレシーバよりも長いものを |与えたときにはどうなるんでしょうか。 今回の実装では、一番短いEnumerableからの要素を使いきった時点 で停止します。Clojureもそういう挙動でした。 http://code.activestate.com/recipes/511480-interleaving-sequences/ で紹介されているPython版は、なぜか残ったものを取り出し続ける 挙動になっていますが、これは使いにくいんじゃないかなあ。 まつもと ゆきひろ /:|)