2012/02/21

FSet を Series 化してみて思ったこと

FSet は Cliki の Current recommended libraries になっているコレクションライブラリ。そうなんだ。

確かになんかよさそう。

でも mapcar にあたる image は引数にコレクションを一つしかとれないの? という疑問に対して、たいして調べることなく scan-fset と collect-fset を定義して Series 化してみた。

FSet と Series と相性いいんじゃないかな。

(series::defS scan-fset (fset)
"scan fset"
(series::fragl ((fset)) ; args
((items t)) ; rets
((items t) ; aux
(fsetptr t fset)
(seqp boolean))
() ; alt
((setq seqp (fset:seq? fset))) ; prolog
((if (fset:empty? fsetptr) (go series::end)) ; body
(if seqp
(progn
(setq items (fset:first fsetptr))
(setq fsetptr (fset:less-first fsetptr)))
(progn
(setq items (fset:arb fsetptr))
(setq fsetptr (fset:less fsetptr items)))))
() ; epilog
() ; wraprs
nil)) ; impure

(series::defS collect-fset (seq-type &optional (items nil items-p))
"(collect-fset [type] series)"
(let ()
(unless items-p
(setq items seq-type)
(setq seq-type 'fset:bag))
(cond ((eq seq-type 'fset:bag)
(series::fragl ((items t)) ((bag))
((bag 'fset:bag (fset:bag)))
()
()
((setq bag (fset:with bag items)))
()
()
nil))
((eq seq-type 'fset:seq)
(series::fragl ((items t)) ((seq))
((seq 'fset:seq (fset:seq)))
()
()
((setq seq (fset:with seq (fset:size seq) items)))
()
()
nil))
((eq seq-type 'fset:set)
(series::fragl ((items t)) ((set))
((set 'fset:set (fset:set)))
()
()
((setq set (fset:with set items)))
()
()
nil))))
:trigger t)

(collect-fset (* (scan-fset (fset:set 1 2 3))
(scan-fset (fset:seq 1 2 3))
(scan-fset (fset:bag 1 2 3))
(scan-fset (fset:map (1 'a) (2 'b) (3 'c)))))
;;=> #{% 1 16 81 %}

(collect-fset (scan-fset (fset:seq 1 2 2 3)))
;;=> #{% 1 (2 2) 3 %}
(collect-fset 'fset:bag (scan-fset (fset:seq 1 2 2 3)))
;;=> #{% 1 (2 2) 3 %}
(collect-fset 'fset:seq (scan-fset (fset:seq 1 2 2 3)))
;;=> #[ 1 2 2 3 ]
(collect-fset 'fset:set (scan-fset (fset:seq 1 2 2 3)))
;;=> #{ 1 2 3 }

0 件のコメント: