各要素に平等なconcat

30分プログラム、その667。各要素に平等なconcatを作ってみる。
リストの結合は(append xs ys zs)でできますけど、xsが全部登場したあとにysが始めて登場するので、ysやzsにはちょっと不公平です。

具体的には、

;; urlからファイルをダウンロードする関数
(define (download-from-url (url) ...)

;; サイトAから落とすファイルリスト
(define as '("http://a.example.com/a"
	     "http://a.example.com/b"
	     "http://a.example.com/c"))

;; サイトBから落とすファイルリスト
(define bs '("http://a.example.com/d"
	     "http://a.example.com/e"
	     "http://a.example.com/f"))

(for-each download-from-url (append as bs))

みたいなシチュエーションだと、サイトAからのダウンロードが全部終わってから、サイトBからのダウンロードが始まるのが嫌じゃない?という話。

そこで、

gosh> (concat '(a b c) '(A B C))
(a A b B c C)

みたいに、各リストから平等に要素をとってきて、つなぐ関数を書いてみました。

使い方

gosh> (concat '(a b c) '(A B C))
(a A b B c C)
gosh> (concat '(a b c) '(A B C) '(0 1 2 3 4))
(a A 0 b B 1 c C 2 3 4)

ソースコード

#! /opt/local/bin/gosh
;; -*- mode:scheme; coding:utf-8 -*-
;;

(use srfi-1)
(define (transpose xs)
  (if (null? xs)
      xs
      (cons (map car xs)
	    (transpose (filter pair? (map cdr xs))))))

(define (concat . xs)
  (apply append (transpose xs)))