22日目
構造型とか全部スコットエンコーディングでええやん.
2.7.4 Pairs
pair型を作る.
MkPair = Pack{1,2}
まだcase式がないので
f p =case p of
<1> a b -> b*a*a
みたいなことができないのでcasePairプリミティブを作る.
carとcdrはcar = casePair p K; cdr = casePair p F
みたいな感じ.自明.
Exercise 2.22
casePairのための状態遷移関数を完成させよ.通常では2つのルールが必要である:1つ目の引数が評価済みかそうでないかである.
上に書いてある必要な変更を実装せよ.
実装をテストせよ.
h | |
---|---|
a | NPrim casePair |
ap | NAp a p |
af | NAp ap f |
p | NData 1 [x, y] |
ap' | NAp a z |
a : ap : af : [] | d | h[ap: NAp a p] | f |
---|---|---|---|
af : [] | d | h[af: NAp b y; b: NAp f x] | f |
a : ap' : af : [] | d | h[ap': NAp a z] | f |
---|---|---|---|
z : [] | (ap' : af : []) : d | h | f |
main = fst (snd (fst (MkPair (MkPair 1 (MkPair 2 3)) 4)))
で試したら2が出てきたから多分出来てる.
2.7.5 Lists
pairとlist何が違うの問題(scheme脳).まあn-タプル(n=2)とリストみたいなもんか.
casePairは1つの'継続'を取る.caseIfは2つの'継続'を取る.caseListはこれらの組み合わせである.
caseList Pack{1,0} cn cc = cn
caseList (Pack{2,2} x xs) cn cc = cc x xs
Exercise 2.23
Core-LanguageでのCons, Nil, head, tailの定義を書け.headとtailを定義するにあたり,abortというプリミティブが必要になるだろう.これはheadもしくはtailが空リストを受け取ったときに返す関数である.abortはとりあえずホスト言語の強制終了として実装すれば良い.
Nil = Pack{1, 0}
Cons = Pack{2, 2}
head l = caseList l abort head'
head' x xs = x
tail l = caseList l abort tail'
tail' x xs = xs
とする.FalseとNilが区別できないが意図したものか?
あとConsの第二引数はlist型が求められるが型解析してないのでill-formed listが作れて困るんじゃないか?
Exercise 2.24
caseListのための状態遷移関数を完成させよ.これとabortを実装し,preludeDefsにCons, Nil, head, tailを追加せよ.
実装をテストするために何らかのプログラムを書け.
h | |
---|---|
a | NPrim caseList |
al | NAp a l |
acn | NAp al fcn |
acc | NAp acn fcc |
an | NAp a n |
n | NData 1 [] |
l | NData 2 [x, y] |
ap | NAp a z |
a : an : acn : acc : [] | d | h[an: NAp a n] | f |
---|---|---|---|
acc : [] | d | h[acc: NInd fcn] | f |
a : al : acn : acc : [] | d | h[al: NAp a l] | f |
---|---|---|---|
acc : [] | d | h[acc: NAp b y, b: NAp fcc x] | f |
a : ap : acn : acc : [] | d | h[ap: NAp a z] | f |
---|---|---|---|
z : [] | (ap : acn : acc : []) : d | h | f |
Exercise 2.25
case式を実装せずに型ごとについてcaseプリミティブを実装する時の欠点は何か?
→新しい型を作るときに同時に実装しないといけないので面倒なのと,caseXXXという名前が増えて解りづらい,くらいか?
2.7.6 Printing lists
暗黙のうちに結果は数値だと思ってきたけどlist型追加したしlist型の可能性もあるよね.
副作用を持つプリミティブ,printとstopを実装する.(printList main)
のようになるようにcompileを変更する.
新しい状態 output を追加する,とか言いやがって分割代入で書かれた関数がどんだけ影響受けると思ってんだこの野郎.
Exercise 2.26
→やったぞこの野郎.これmainが数値を返すと死ぬからcompileは変更してないし,printの状態遷移ルールを足しただけで実際にはprintできないけどな.