GaucheでHaskellのscanl
Haskellのscanlに相当するものがなかったので書いた.
(修正 9:24)
(use gauche.collection) (define (scan-with-iterator+builder f seed end? next add! get) (let loop ((seed seed)) (add! seed) (if (end?) (get) (loop (f (next) seed))))) (define-method scan-to ((class <class>) f seed (coll <collection>)) (with-iterator (coll end? next) (with-builder (class add! get) (scan-with-iterator+builder f seed end? next add! get)))) (define-method scan (f seed (coll <collection>)) (scan-to <list> f seed coll)) (define-method scan1-to ((class <class>) f (coll <collection>)) (with-iterator (coll end? next) (with-builder (class add! get) (if (end?) (get) (scan-with-iterator+builder f (next) end? next add! get))))) (define-method scan1 (f (coll <collection>)) (scan1-to <list> f coll))
コールバックの引数の順序はfoldやmap-accumに倣った.
(追加 10:07)scan-right
(use gauche.sequence) (define-method scan-right (f seed (coll <sequence>)) (with-iterator (coll end? next) (call-with-values (rec (loop) (if (end?) (values seed '()) (let1 v (next) (receive (seed r) (loop) (values (f v seed) (cons seed r)))))) cons))) (define-method scan-right-to ((class <class>) f seed (coll <sequence>)) (coerce-to class (scan-right f seed coll))) (define-method scan-right1 (f (coll <sequence>)) (with-iterator (coll end? next) (if (end?) '() (call-with-values (rec (loop) (let1 v (next) (if (end?) (values v '()) (receive (seed r) (loop) (values (f v seed) (cons seed r)))))) cons)))) (define-method scan-right1-to ((class <class>) f seed (coll <sequence>)) (coerce-to class (scan-right1 f seed coll)))
汚い…なんとかならんのか.