Reasoned Schemer (47) 10章 append-inf
conde
のモトになっているdisj2
とそのヘルパー関数append-inf
append-inf
から見よう
(define (append-inf s-inf t-inf)
(cond
((null? s-inf) t-inf)
((pair? s-inf) (cons (car s-inf) (append-inf (cdr s-inf) t-inf)))
(else (lambda () (append-inf t-inf (s-inf))))))
s-inf
がnullならt-inf
を返し
s-inf
がpairならs-inf
のcarと、s-inf
のcdrとt-inf
をappend-inf
したもののconsを返す
ここまでならリストを引数に取る普通のappend
append-inf
はstreamを引数に取るので第3の場合分けがある
s-inf
がnullでもpairでもなければsuspensionなので
else
はs-inf
がsuspensionのときは、の意
(s-inf)
はsuspensionの中身を取り出すということ
t-inf
と(s-inf)
の順が逆になっているのは・・・
s-inf
がsuspensionのときはt-inf
を先にやってみることにする、ってことかな
しかしその場で評価してしまうのではなくいったん全体をsuspensionにする
順番を変えてるところは
よくわかんない順番に結果が出てくるあたりとからんでる雰囲気を感じる
ここであっちやってはこっちやる、みたいな動きをするおかげで
いろんな可能性をちょっとずつ試すような動きになってるんじゃないかなあ
練習
> (append-inf '() '(a b c))
(a b c)
> (append-inf '(d e f) '(a b c))
(d e f a b c)
> (define susp1 (lambda () '(g h i)))
> (define susp2 (lambda () '(j k l)))
> susp1
#<procedure:susp1>
> (susp1)
(g h i)
> (append-inf susp1 '(a b c))
#<procedure:...r/minikanren.scm:50:10>
> ((append-inf susp1 '(a b c)))
(a b c g h i)
> (append-inf susp1 susp2)
#<procedure:...r/minikanren.scm:50:10>
> ((append-inf susp1 susp2))
#<procedure:...r/minikanren.scm:50:10>
> (((append-inf susp1 susp2)))
(g h i j k l)