2020 年 4 月

2020-04-15 (Wed)

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 (Tue)

[Bunny] スーパークラスをもつクラスの扱い

今日は、仕掛中の 023 を継続。スーパークラスをもつクラスを扱えるようにして、 mycompare4.hs が通るようになった。

クラス宣言のリネームでスーパークラスを捨ててしまっていたのをなおしたり、 runtime における辞書が多重継承できないのを直す必要があったり、なかなか面白かった。

この過程でみつけた他の不具合については、別イシューを立てたので、次は、 以下のように進めるのがいいのではないかな。

023ができたら、各インスタンスの定義を minimum complete definition にして、 余計なコードは消そう。

2020-04-13 (Mon)

Bunny しんちょく

在宅勤務で、通勤時間がへったのと、リモートワークのために自宅のPC環境を整えたせいか、 すこし進捗するようになった。

これは難しいかもと思われた 009 がクリアできたのがうれしい。 やっぱり thih の Typing モジュールは間違っていなかった。

残りの Issues に関する覚書:

001, 002, 020, 022 あたりは、型に関するエラーなんだけど、原因にめぼしがついてない。

2020-04-08 (Wed)

型コンストラクタの名前解決がハードコードされてたのを直した。

#004 を直した。 なまえに qualifier がついていたときの処理などはあとまわし。

これをやったので、つぎは adt-sample4.hs を通るようにできるとおもう(003)。

2020-04-06 (Mon)

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 やランタイムに追加

それでも、まだ 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 (Sun)

1年ぶりの再開 [Bunny]

自作コンパイラの制作ノートを久々にひらく。前回なにか記入したのが 2019年3月4日なので一年ぶり以上だが、その前もまた1年ちかくあいていたり。 完全な放置プロジェクトになってた。

ほそぼそとでも再開しよう。

状況の確認

Rename.hs

このモジュールは、Parser の出力する抽象構文 (Absyn) を変換して、型推論可能な形にする。 主な仕事は以下の通り:

…なのだが、このフェーズでは、上記以外に行わねばならないこととして、型やクラス、データ宣言の処理がある。 これらについては積み残しとなっていて、以前書いた記事 でも全く述べていない。

しばらくは、この Rename.hs モジュールに手をくわえながら、解説メモ を書いていくことにする。

久々にみたノートの記述からみると、未処理の宣言のうち 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]" を処理できるようにしてみた。 そこでの各テストケースの状況:

2020-04-01 (Wed)

よくみる継続価値の式、簡単そうなんだけど自分で導出しようとしても、 同じにならないのでなんでかと思って調べたので、書き出しておいた: 継続価値式 (Cash Flow Perpetuity Formula)

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