Reasoned Schemer (005) caro、cdro、conso
2. Teaching Old Toys New Tricks
Don't put new wine into old bottlesのもじりだったりするんだろうか
あんまり関係ないかな
そういうとこ気にしなきゃいけないとこが多そうで翻訳はちょっとたいへんそうだな
SICPとかマジメなやつのほうがある意味楽そう
さてcar
の論理版?caro
というのが出てきます
(run* q (caro '(a c o r n) q))
とやるとq
が'a
になるという
定義
(defrel (caro p a)
(fresh (d)
(== (cons a d) p)))
p
のcar
がa
である、とは
a
と何かをcons
するとp
になる、ということである
と読めばいいかな
あんまり意識してなかったけど関数も普通に使えるんだな
car
とcaro
を混乱しないようにしないと
(car (cdr (cdr '(a c o r n))))
といった式を関係型に書き直すときに
中間的な変数を使って入れ子を外していくことをunnestingといいます
(run* r
(fresh (v)
(cdro '(a c o r n) v)
(fresh (w)
(cdro v w)
(caro w r))))
こうでもいいのかな?
(run* r
(fresh (v w)
(cdro '(a c o r n) v)
(cdro v w)
(caro w r)))
なんかダメな理由あったっけ・・・?
cdro
、conso
も出てきて
(caro p a)
p
のcar
はa
(cdro p d)
p
のcdr
はd
(conso a d p)
a
とd
のcons
はp
結果が右に来る、っていうのがお作法なんだなきっと
(defrel (conso a d p)
(caro p a)
(cdro p d))
caro
とconso
はcons
で定義して、conso
はcaro
とcdro
で定義している
conso
をcons
で定義することはできないのかな?
と思ったらこういう定義も書かれている
(defrel (conso a d p)
(== `(,a . ,d) p))
突然のドット記法
当然こうも書けるはず
(defrel (conso a d p)
(== (cons a d) p))
caro
やcdro
だってcar
やcdr
で書けるはずか・・・
(defrel (caro p a) (== (car p) a))
(defrel (cdro p d) (== (car p) d))
caro
やcdro
をcons
で書いて、
conso
をcaro
やcdro
で書いてるのは、
できるだけSchemeの関数に依存しないように、ってことかな
cons
が基礎中の基礎ってことになるんだろうか
なにせ偉大なるcons様だからな
oはなんの意味かと思ってたけど、単にSchemeの関数と見分けるためだけのものかもしれないなあ
なにに由来しているのかはわからない