多値メモ

多値のメモ。


とりあえずMzSchemeのデフォルトで使えるのが、

(call-with-values (lambda ()
                    (values 2 3))
                  (lambda (a b)
                    (list a b)))

valuesで多値を投げて、lambdaで受け取る。


SRFI-8で定義されてるレシーバマクロを使うと、ちょっと短く書ける。

(require (lib "8.ss" "srfi")) ; MzScheme用

(receive (a b)
         (values 1 2)
         (list a b))

短くなった。


take-dropなるものを作ってみたら、

(define (take-drop l n)
  (cond ((null? l) (values '() '()))
        ((zero? n) (values '() l))
        (else
          (receive (t d)
                   (take-drop (cdr l) (- n 1))
                   (values (cons (car l) t)
                           d)))))

(receive (a b) (take-drop (iota 10) 5)
         (list a b))
; ((0 1 2 3 4) (5 6 7 8 9))

案外めんどくさかったり。


で、もうちょっと調べてみると

(receive (a b)
         (split-at (iota 10) 5)
         (list a b))
; ((0 1 2 3 4) (5 6 7 8 9))

SRFI-1にsplit-atがあったりして、ちょっと悲しくなったり。


んじゃ多値ってどうなってんだ!?という疑問が湧いてくるので、作ってみる。

(define (values . v) v)

(define (call-with-values v f)
  (apply f (v)))

valuesはリストになっちゃってるので、工夫したほうがよさげ。


もうcall-with-valuesとかreceiveとか呼ぶの面倒過ぎるので、

(define (take-drop l n)
  (cond ((null? l) (list '() '()))
        ((zero? n) (list '() l))
        (else
          (apply (lambda (t d)
                   (list (cons (car l) t) d))
                 (take-drop (cdr l) (- n 1))))))

(apply (lambda (a b) (list a b))
       (take-drop (iota 10) 5))
; ((0 1 2 3 4) (5 6 7 8 9))

これでいいんじゃね。


するっと、Haskellのx:xsが実装出来そうな予感がしてくる訳。

(define (head l)
  (apply (lambda (x . xs) x)
         l))

(define (tail l)
  (apply (lambda (x . xs) xs)
         l))

(head '(1 2 3 4 5)) ; 1
(tail '(1 2 3 4 5)) ; (2 3 4 5)

おぉ!!


で、apply使わなくてもいいんじゃねぇかという話題が出てくる。

(define (take-drop l n cont)
  (cond ((null? l) (cont '() '()))
        ((zero? n) (cont '() l))
        (else
          (take-drop (cdr l)
                     (- n 1)
                     (lambda (t d)
                       (cont (cons (car l) t) d))))))

(take-drop (iota 10) 5 (lambda (x y) (list x y)))
; ((0 1 2 3 4) (5 6 7 8 9))

継続渡しスタイルで多値が書けるらしい。valuesよりは断然楽。

CPSで多値

ほほぅ。おもろい。


そんなメモでした。