Schemeで、ある関数に多値を返す複数の関数の戻り値を効率よく渡す方法ってないもんかなぁ。イメージ: (apply-values list (values 1 2 3) (values 4 5 6)) => (1 2 3 4 5 6)みたいなことをやりたい訳です。何となくマクロでできそうな気はしているんだけど、エレガントな方法を思いつかない...
マクロは良くわからないので (スコア:1)
(use srfi-11)
(define (main args)
(let-values ((a (values 1 2 3))
(b (values 4 5 6)))
(display (append a b))
(newline)))
効率的な例は、他の人に期待 ;-)
-- cooper
Re:マクロは良くわからないので (スコア:1)
うーん。やっぱりリストにして渡すしかないんでしょうかねぇ...
ちょっとやってみた (スコア:1)
(define (pa$-with-multi-values proc mv-proc-list)
(letrec-syntax
((pa$-with-values
(syntax-rules ()
((_ proc producer)
(call-with-values (lambda () producer) (lambda args (apply pa$ proc args)))))))
(if (null? mv-proc-list)
proc
(pa$-with-multi-values (pa$-with-values proc ((car mv-proc-list)))
(cdr mv-proc-list)))))
(define-syntax call-with-multi-values
(syntax-rules ()
((_ consumer producer ...)
(call-with-values (pa$-with-multi-values values (list producer ...)) consumer))))
(define (main args)
(display (call-with-multi-values vector
(lambda () (values 1 2 3))
(lambda () (values 4 5 ))
(lambda () 6)))
(newline))
;;; なーんかエレガントにいかんのよねぇ。
;;; 結局、applyするとこでlist作ってるし。
Re:ちょっとやってみた (スコア:1)
うっかりcall-with-multi-valuesなんて名前にしちゃったが、引数の順序がcall-with-valuesとは違っている(意味的には逆になっている)から、別の名前にした方がいいんだよね。apply-multi-valuesとかも考えてみたけど、値に相当する部分にも手続きを渡すのがちょっとなぁ...
# というか、慣れないせいかもしれないけど、Schemeの多値って使いにくい