# 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)
自分でやって合わなかった理由は、
初年度のフリーキャッシュフローも、資本コストによって割り引かれるようにしてなかったから、だった。