Reasoned Schemer (28) わり算 続き
splito
は数をふたつの部分に分けてくれるわけですが
splito
は他にどんなことをしますか?
splito
は関係ですから、下位ビットのl
と上位ビットのh
を結合してn
を作ることができます。r
の長さを使ってパディングビットを詰めます。
こういうの聞くと関係に名前をつけるのが悩ましくなるな
結合でもあり分割でもある
関係なんだから動詞にしちゃいけないのかな
なぜ
splito
の定義はこんなに複雑なのでしょうか?
そうそれ
splito
は(0)
で数を表さないようにしないといけないからです。
そうだねー
表現がよくないってことかなあ?
でももっとキレイなやりかたというのも思いつかない
splito
はどうやって(0)
ができないようにしているのですか。
n
を下位ビットと上位ビットに分けたあと、右側の0
を取り除いています。
ん、そんなことしてたっけ?
むー
字面だけ眺めててもわからなくなってきたなあ
Little Schemerのときみたいに書き下していけるといいんだけど
あんまりうまくかける気がしないんだよなあ
でもやってみよう
ここからスタート
(splito '(0 0 1 0 1) '(0 1) l h)
--- (1)
これは4行目と6行目にマッチする
まずは4行目の方から
(splito '(0 1 0 1) '(1) '() h)
--- (2)
これも4行目と6行目にマッチする
また4行目の方から
(splito '(1 0 1) '() '() h)
これは3行目にマッチして・・・と思ったけどl
が()
に確定しちゃってるからマッチしない
ということはこのルートは失敗ってことになるわけか
ひとつもどって(2)
6行目にならマッチするかなと思ったけど l がマッチしない
もうひとつ戻って(1)
これは6行目にもマッチする
(splito '(0 1 0 1) '(1) ^l h), lは `(0 . ,^l)
4行目にはマッチしなくて6行目にマッチ
(splito '(1 0 1) '() ^l h), lは `(0 0 . ,^l)
ちょっと書きづらいなあ
でももう少し
これは無事3行目にマッチして
h
が(0 1)
で^l
が(1)
、つまりl
が(0 0 1)
ということ
お、できたか
読み方が甘かった
h
やl
を求める、っていう意識になっちゃってた
2行目で言えば単に
n の最下位ビットが 0 で r が
()
なら
h は n の cdr で l は()
と思ってたけど、l
が変数のときか()
のときにしかマッチしないんだな
l
が()
なら単にマッチするだけ、l
が変数なら()
になる、と
文章では書けなくなってきたぞ
他の引数も同じだし
でもこれで理解できるようになったかも?
次はl
の右側の0がなくなる例でやってみよう