# 2020 年 4 月 ## 2020-04-15 ### git prompt なんとなく、Windows の git bash の設定に見慣れてしまったので、Linux 上でも。 $$
{ source ~/.git-prompt.sh export PS1='\[\e[1;32m\]\u@\h\[\e[m\] \[\e[1;33m\]\w\[\e[m\] \[\e[1;36m\]$(__git_ps1 " (%s)")\[\e[m\]\n\$ ' $$} ## 2020-04-14 ### [Bunny] スーパークラスをもつクラスの扱い 今日は、仕掛中の [023](bissue023) を継続。スーパークラスをもつクラスを扱えるようにして、 mycompare4.hs が通るようになった。 クラス宣言のリネームでスーパークラスを捨ててしまっていたのをなおしたり、 runtime における辞書が多重継承できないのを直す必要があったり、なかなか面白かった。 この過程でみつけた他の不具合については、別イシューを立てたので、次は、 以下のように進めるのがいいのではないかな。 - 単純なケースで 008 は片付けてしまう(ガードをすべてサポートしようとすると時間かかりそう) - そうすると、023 は一緒に解決しそう 023ができたら、各インスタンスの定義を minimum complete definition にして、 余計なコードは消そう。 ## 2020-04-13 ### Bunny しんちょく 在宅勤務で、通勤時間がへったのと、リモートワークのために自宅のPC環境を整えたせいか、 すこし進捗するようになった。 これは難しいかもと思われた [009](bissue009) がクリアできたのがうれしい。 やっぱり thih の Typing モジュールは間違っていなかった。 残りの Issues に関する覚書: - [023](bissue023) 仕掛中。009 が片付いたのであと少しでは - [008](bissue008) これも 009 が片付いたのでねらい目 - [013](bissue013) これは reject かな - [024](bissue024) これも、式変形の問題なので、やればやれそう。 001, 002, 020, 022 あたりは、型に関するエラーなんだけど、原因にめぼしがついてない。 ## 2020-04-08 ### 型コンストラクタの名前解決がハードコードされてたのを直した。 [#004](bissue004) を直した。 なまえに qualifier がついていたときの処理などはあとまわし。 これをやったので、つぎは adt-sample4.hs を通るようにできるとおもう(003)。 ## 2020-04-06 ### Int と Integer の違い? [Bunny] adt-sample2.hs がエラーになる(そして Int を Integer に変えると通る)理由を 考えてみる。 最初に疑ったのは、整数リテラルの方を Integer 決め打ちにしてしまっていないか (本来は Num t => t) だったが、これはシロだった。 整数リテラルは、Rename によって Lit (Litint i) に変換されるが、 Typing における tiLit (LitInt _) をみれば正しい型が付けられているのがわかる。 つぎに、Types をみると、以下があやしい: $${ tInt :: Type tInt = TCon (Tycon "Int" Star) tInteger :: Type tInteger = TCon (Tycon "Prelude.Integer" Star) $$} ここは、Int も Prelude.Int に直しておく。 つぎに、Num クラスのインスタンスに Prelude.Int もなっているかなぁという目でみていると、 Typing の以下のところが怪しい: $${ numClasses :: [Id] numClasses = ["Prelude.Num", "Prelude.Integral", "Prelude.Floating", "Prelude.Fractional", "Prelude.Integer", "Prelude.Real", "Prelude.RealFloat", "Prelude.RealFrac"] $$} ここに、"Prelude.Int", も加えれば、ひとまず通るようにはなるのかな…と思ったら、ならず。 原典(Typing Haskell in Haskell) を確認すると、ここには "Integer" もいらなかった。 あれー、なんで加えたんだ? とりあえず、ただしく、取り除いておいた。 $${ numClasses :: [Id] numClasses = ["Prelude.Num", "Prelude.Integral", "Prelude.Floating", "Prelude.Fractional", "Prelude.Real", "Prelude.RealFloat", "Prelude.RealFrac"] $$} ### lib/Prelude.hs じゃぁ、いったいどこで Integer だけを Num クラスにいれて、 Int をいれていないんだろう?とおもって、app/Main.hs からたどっていくと… $${ initRnState :: RnState initRnState = let ifxenv = insert "Prim.:" (Fixity RightAssoc 5) Symbol.empty in RnState { rnModid = "" , rnLvs = [] , rnTenv = Symbol.empty , rnIfxenv = ifxenv , rnCe = initialEnv -- preludeClasses , rnCms = primConsMems , rnKdict = Symbol.empty , rnCdicts = [] , rnConsts = emptyConstInfo } $$} あれ、preludeClasses はコメントアウトされていて、initialEnv にかわってる (ってことは、preludeClasses は未使用なのか)。 そうだ。lib/Prelude.hs をまずコンパイルするようにしてた(わすれてた)。 というわけで、[lib/Prelude.hs に Int に関する記述をついかし、それをコンパイルするのに必要な組み込み関数の定義を Predefined やランタイムに追加](https://github.com/unnohideyuki/bunny/commit/3e560319b7bbb5d654ecdc77997cc884a850cab5) それでも、まだ adt-sample2.hs は通らない(また別のエラーに)が、make check は通ったので、ひとまず、今日はこんなところか。 x :: Integer と x :: Int の違いを比べる、もっと単純なテストケースをつくって追ったほうがよさそう。 ⇒ intinteger[1-2].hs をつくったが、これらは通ってしまった。adt-sample2.hs がエラーするのは別の理由らしい。 adt-sample2.hs をエラーが再現する最小まで縮めた: atd-sample2x.hs ## 2020-04-05 ### 1年ぶりの再開 [Bunny] 自作コンパイラの制作ノートを久々にひらく。前回なにか記入したのが 2019年3月4日なので一年ぶり以上だが、その前もまた1年ちかくあいていたり。 完全な放置プロジェクトになってた。 ほそぼそとでも再開しよう。 ### 状況の確認 - adt-sample.hs は通っている (sample126.hs) - deriving Show が積み残されている - adt-sample2.hs は NG - Int を Integer に変えたバージョンは通る(sample128) - Hoge 10 をスキップしても通る。定数リテラルの型付けまわりか? - Rename まわりが次のターゲットになっていたよう ### Rename.hs このモジュールは、Parser の出力する抽象構文 (Absyn) を変換して、型推論可能な形にする。 主な仕事は以下の通り: - 結合性の解決 - 変数のリネーミング(α変換) - 脱糖 (desugar) - パターンマッチの変換(これは脱糖の一種といえるかも) …なのだが、このフェーズでは、上記以外に行わねばならないこととして、型やクラス、データ宣言の処理がある。 これらについては積み残しとなっていて、[以前書いた記事](HaskellInHaskell) でも全く述べていない。 しばらくは、この Rename.hs モジュールに手をくわえながら、[解説メモ](bunny_Rename) を書いていくことにする。 久々にみたノートの記述からみると、未処理の宣言のうち DataDecl(抽象データ型)から手をつけようとしていたようだ。 そこで、いま引っかかっているのは、型シグネチャの処理(adt-sample3) や、adt-sample4 は…なにかな。 これらの次に、deriving Show あたりをサポートしようとしていたらしい。 ### renSigdoc Sigdoc の処理にとりかかるにあたって、testcases を2つつくってみた。 sigdoc1.hs $${ main = putStrLn s where s :: [Char] s = "Hello, world!" $$} sigdoc2.hs $${ s :: String s = "Hello, world!" main = putStrLn s $$} 2の方が(型シノニムの実装がいるので)難しいかと思ったら、こちらはすでに通ってしまった。 これは、現状の renSigdoc におけるハードコーディングのせいらしい。 $${ -- TODO: should be fix this hard coding. renSigdoc (A.Tycon n) _ = case origName n of "Integer" -> return tInteger "Int" -> return tInt "String" -> return tString "IO" -> return $ TCon (Tycon "IO" (Kfun Star Star)) "()" -> return tUnit "Bool" -> return tBool s -> error $ "renSigDoc $ A.Tycon " ++ s $$} このあたりを、きちんと作っていくんだな。 わざと間違った型宣言をした sigdoc2err.hs はきちんと型エラーになったので、 すでに型宣言を型推論器にわたす経路はできている模様。 ### 今日の状況 renSigdoc をハードコーディングのままだが "Char" -> tChar を追加して、とにかく "[Char]" を処理できるようにしてみた。 そこでの各テストケースの状況: - sigdoc1.hs: doCompile ... bunnyc: Variable not found: Main.l0.l0.s - sigdoc1b.hs: ok - sigdoc2.hs: ok - sigdoc2err.hs: 期待通りに型エラーとなる ## 2020-04-01 よくみる継続価値の式、簡単そうなんだけど自分で導出しようとしても、 同じにならないのでなんでかと思って調べたので、書き出しておいた: [継続価値式 (Cash Flow Perpetuity Formula)](CacheFlowPerpetuity) 自分でやって合わなかった理由は、 初年度のフリーキャッシュフローも、資本コストによって割り引かれるようにしてなかったから、だった。