Reasoned Schemer (52) 10章 conj2
(define (conj2 g1 g2)
(lambda (s) (append-map-inf g2 (g1 s))))
disj2
と似てるような似てないような
disj2
はappend-inf
を呼んでるけどconj2
はappend-map-inf
を呼ぶ
disj2
はg1
もg2
もs
に適用されるけどconj2
はg2
だけ
g1
とg2
が非対称なんだ
append-map
ってなんだっけ
append-map
is like map, but it usesappend
instead of cons to build its result.
cons
のかわりにappend
を使うmap
ということらしい
else
以外の形を見ると確かにそう
else
は何をやっているかというとsuspensionだったらforceしてるだけ
cons
のかわりにappend
を使うとどうなるかって微妙にイメージできてないんだけど
> (append-map-inf (lambda (l) (map sub1 l)) '((1) (2 3) (4 5 6)))
(0 1 2 3 4 5)
> (map (lambda (l) (map sub1 l)) '((1) (2 3) (4 5 6)))
((0) (1 2) (3 4 5))
あんまりすっきりした例が思いつかなかったけどこういうことかな
(g1 s)
はsubsitutionのstreamだから
(append-map-inf g2 (g1 s))
は(g1 s)
の各要素(substitution)に
g2
を適用した結果(substitutionのstream)をappend-inf
する
substitutionのstreamをappend-inf
すると全体がひとつの大きなstreamになる、
ってことであってるかな
ちょっと実例がほしい
> (append-map-inf (== 'olive x) ((== 'oil y) empty-s))
(((#(x) . olive) (#(y) . oil)))
> ((conj2 (== 'olive x) (== 'oil y)) empty-s)
(((#(y) . oil) (#(x) . olive)))
> (append-map-inf (== 'olive x) ((== 'oil x) empty-s))
()
> ((conj2 (== 'olive x) (== 'oil x)) empty-s)
()
なんかちゃんとできてるところがびっくりする
なんでこうなるんだっけ(わかってない
disj2
のとき、substitutionのstreamって結局何なの?と思ったけど
思考を放棄してたやつ、手掛かり増えたかな?
何か見えた気もするんだよな