Clojure > Archives > 2010/04/17

2010/04/17 16:19:00 UTCfatrow
#
(map inc [1 2 3]) で (2 3 4) じゃなくて [2 3 4] を返してもらうには vec を適用させるしかないですか?(vec (map inc [1 2 3])) 。(2 3 4) は見た目リストだけど、別にリストに変換されたわけじゃないらしいのでvecに再変換しない方法もあるのかなぁと思って。
2010/04/17 16:29:02 UTCshiro
#
mapの戻り値はリストではなくシーケンスですよ。REPLが表示の時にリストに変換してるだけです。
#
user=> (class (map inc [1 2 3]))
clojure.lang.LazySeq
2010/04/17 16:32:15 UTCfatrow
#
関数によって違うのかなぁ

user> (class (rest [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq
2010/04/17 16:32:38 UTCshiro
#
中身の実装は違いますが、Clojure的にはどちらもシーケンスです。
#
どうしてもベクタが欲しければ一般的にはvecを再適用するしかないと思いますが (変換後のシーケンスをランダムアクセスしたい、とか)、大抵はシーケンスのままでも扱いやすいんじゃないかと。
#
効率を考えてvec専用関数が用意されてるものもあるんですが、vec専用mapってあったっけな?
2010/04/17 16:35:39 UTCfatrow
#
(map f coll) の coll にはベクタやリストやセットの何が入るか分からなくて、結果を同じ型で欲しいんですが結局データ型の数だけ分岐を書かないといけないんですね
2010/04/17 16:41:55 UTCshiro
#
一般には、map後のシーケンスを元の型に変換する方法が一意に定まらないので、汎用的に書くのは無理じゃないでしょうか (e.g. マップにmapして、fがkey/valueペアでなく単一の値を返した場合、結果のマップはどうなるべきか、とか、セットにmapしてfが返した値がそれぞれユニークでない場合に同じ値をまとめちゃってもいいものか、とか)
#
あとstringにmapしてf ga
#
fが文字を返さなかった場合にどうする、とか。
2010/04/17 16:42:49 UTCfatrow
#
そうですね。よく考えたら無理ですね。
#
オプションとかで指定できれば嬉しいな
2010/04/17 16:50:45 UTCshiro
#
ありそうな話なので、誰かが既に書いてるかもしれませんが。