http://jlongster.com/blog/2009/08/1/scheme-snippet-1/ という記事を見て、unfold は便利だと再発見しました。何か他にも応用例がないか考えてみたところ、以下のようなものが思いつきました。
mod_lisp のプロトコルでは、Apache から application server にあたる Lisp 側へのリクエストのヘッダを次のように送ってきます:
mod_lisp sends header and connection parameter values to the Lisp process. For each key/value pair: The key is sent as a newline terminated line, then the value is sent as another line. When all key/values have been sent, the string "end\n" is sent
例えば Apache への1リクエストにつき
server-protocol HTTP/1.1 method GET url / server-ip-addr 127.0.0.1 server-ip-port 80 remote-ip-addr 127.0.0.1 script-filename /var/www/ remote-ip-port 40857 server-id scheme3000 server-baseversion Apache/2.2.8 modlisp-version 1.3.1 modlisp-major-version 2 Host 127.0.0.1 User-Agent Mozilla/5.0 (X11; U; Linux i686; ja; rv:1.9.0.11) Gecko/2009061212 Iceweasel/3.0.9 (Debian-3.0.9-1) Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language ja,en-us;q=0.7,en;q=0.3 Accept-Encoding gzip,deflate Accept-Charset Shift_JIS,utf-8;q=0.7,*;q=0.7 Keep-Alive 300 Connection keep-alive end
のような内容になります。
嬉しいことに次のように unfold を2つ組み合わせればパースできます:
(call-with-port (open-string-input-port header)
(lambda (port)
(unfold null?
(lambda (x) (take x 2))
(lambda (x) (drop x 2))
(unfold (lambda (x) (string=? "end" x))
(lambda (x) x)
(lambda (x) (get-line port))
(get-line port)))))
ただし header
はヘッダを表す文字列です。