個別に issue を立てようとすると間に合わない、こまごましたメモを以下に。
これ 実際に修正するときには、issue 発行してからにしよう。
0.9 版には、defaulting をちゃんとするのは間に合わなさそう。 その場合、いまは、型検査では default (Integer, Double) を前提にして、 後段の DictPass では Integer への defaulting しかサポートしていないという非対称は取り除いておきたい(つまり、型推論は default (Integer) で行うようにすればいいのではないかと思っている)。
0.9 版のコード名は basecamp でいいのではないだろうか。
114 では、Desugar 時に生成した変数名がプログラム中の変数と衝突してバグっていた。同様の問題がないか、また、変数名の生成規則に一貫性があるか、チェックしたい。
Version 0.9 (code name : learning by imitation (見様見真似)) をリリースしたら、 bissues をすべて印刷しよう。2up 両面にすれば、そんなに大量にはならないはず。 セブンイレブンのネットプリントなどでも、両面印刷はできるようなので。
PDF の連結は…めんどうだけど手作業になるかなぁ。
test/samples/sample285.hs (fromrational.hs) などで、 まだ浮動小数点数リテラルをサポートしていないので、割り算を書いているのだけど、 さらに型注釈をつける必要がある。defaulting 未実装なためだと思っているけど、 要確認。(defaulting 実装後のテストで)
x = toRational (314/100 :: Double) y = toRational (10/3 :: Double)
今日 Types.hs に追加した tRational は次のようになっている:
tRational :: Type tRational = TAp (TCon (Tycon "Prelude.Ratio" (Kfun Star Star))) tInteger
これは、いま一時的に Ratio 定義を lib/Prelude.hs に書いているためだが、 これを Data.Ratio に移動したときには、上記の tRational も変える必要がある。
instance declaration を scan するときに、左辺の関数名を qname として登録しないための 仮対処 がイマイチ。
どどっとテスト追加
入力のあるテストをする仕掛けはまだない。
x `seq` f x としたとき、いまの実装でも確かに先に x が評価されるが、 その評価された x が、ちゃんと f に渡されるんだろうか。評価前を指したままになっていないだろうか??
ddumpAssump と ppTypes などは1つのファイルにまとめたら。
calcFailSc qt [] = let qt' = normQTy qt in (Forall [] qt') -- quantify (tv qt') qt' where normQTy (qs :=> t) = let tvs = tv t qs' = filter (\pr -> case tv pr of [] -> True xs -> (head xs) `elem` tvs ) (nub qs) in qs' :=> t
Rename.renRhs (A.GuardedRhs .. にて、
-- todo cnvGs support most simple case that has only one statement.
I set up Ubuntu on a desktop PC that I have but unused. So, I record the additional packages necessary to build bunny .
In addition, I had to install jdk, sudo apt install openjdk-14-jdk
w3m を入れたので、Emacs で書ける。(「書ける」がなかなか出て来ない感じ、なつかしい)
035を修正した のだが、やや考えていたのと事情がちがった(←のリンク先にすこし目盛った)。 のと、これだと、Case の DEFAULT 節は未使用ってことになるのかな。 本当にいらないのなら削る。
今日の修正 は、 filter (\pr -> head (tv pr) `elem` tv t') のあたり、 pr (Predicate) の tv が一つであることを決めつけたような実装がいまいちだし、 また、DictPass でも似たような簡略化をしていたような気がする。全体的に、要整理。 (ちゃんとコンパイラが仕様を満たすようになってからでいいとは思うが)
DictPass.normQTy も、これでいいのか、とか、必要なのかは、 いずれ統計(normQTy の中に、処理前後で変わるのかとか、head (tv pr) で すてられる情報などを吐き出させる)をとって調べたい。
sample191.hs のエラーのしかたはいまいちな感じ。qname not found ## となって、それ自体は正しい。つまり、a ## b : bs = ... は (a ## b) : bs = ... と解釈されたわけで、ここでは Main.: が再定義されたわけだけど、再定義していいのか (いいのかも)、および、じゃあ ## はコンストラクターパターンにみえたのか? (よくなさそう)
Java FFI のやり方は eta がデファクトなら、それを真似るかなと思ったけど、 frege と二大流派なんでしょうか: https://www.slideshare.net/y_taka_23/haskell-on-jvm-jjugccc-cccl8
どちらも、なんか Haskell 2010 の文法を逸脱しているようにも見える。
Haskell 2010 の FFI は C を前提にしているようだが、この延長でどうにかできないかな? http://yunomu.hatenablog.jp/entry/2012/07/31/005513
特に、. をメソッド呼び出しに使うのは抵抗がある。 Foreign.Ptr で obj を束縛したら、
someMethod obj arg1 arg2 ...
って感じで、メソッドのレシーバを第1引数にとってやれば、よさそうでは?
foreign import jclass "Hoge" newHoge :: JInt -> IO JObject foreign import jmethod "Hoge.fuga" fuga :: JObject -> JInt -> IO ()
みたいに、メソッドひとつにつき、ひとつの foreign import 文という感じ。 コンストラクタは特別(特別にしなくてもいいかな)。
これでもいいけど、なんでも IO じゃなくて、IO or ST 選べるようにしたい (Primitive?) …とおもったけど、ST って Haskell 2010 の範囲外?
unsafePerformIO は欲しくなるかも。trace はそれで実現するとか、 上で書いたように、Java FFI の多くが IO になるなら(大丈夫な場合に)unsafePerformIO で純粋化するとか…
FFI は、ccall なみに単純にしたい。ポインタが全部 JObject では困ってしまいそうなので、 コンストラクタの出力は、そのクラスのポインタということにできないかな。
少なくとも、以下の種類がいりそう
field という名は、Declaring Member Variables より:
There are several kinds of variables:
foreign import jnew "java.lang.StringBuilder" j_StringBuilder :: IO JStringBuilder foreign import jmethod "java.lang.StringBuilder.toString" j_StringBuilder_toString :: JStringBuilder -> IO String foreign import jsmethod "java.lang.Math.abs" j_dabs :: Double -> Double foreign import jsmethod "java.lang.Math.abs" j_iabs :: Int -> Int foreign import jsfield "java.lang.Math.PI" j_PI :: Double
Java の Math.abs は多重定義されているのだが、foreign import 時には単相になるかな。
上の例を書いていて気付いたけど、まだ IO が値を返すようなケースをひとつもつくっていないかも。まずは、そっちだな。
しかし、Math.abs や Math.PI の例は、すぐにでも出来そうでは。
コールバックとかは、どうすんのかなぁ…。
[1..n] や [1..] などは、Haskell Language Report の3章でもうすぐでてくるが、 Enum をきっちり作ってからのほうが、たぶん、いい。
--ddump-absyn で表示されるやつは、fixity resolution 前なのかな?
Rename.renInstDecls 改造中。
lookupKdict qcn とやって、クラス名で kind を引くのはいいとして、 どうやってこれを登録したのか覚えていない。要確認。
ghci に聞くと、こんな感じ:
Prelude> :k Show Show :: * -> Constraint Prelude> :k Monad Monad :: (* -> *) -> Constraint
Show の実装に関して。
(1, "abc", ["a", "b", "c"]) などでテストすべし。
その前に(Pair の前にリスト)、["a", "b", "c"] や [["a", "b"], ["c"], [], ["d", "e"]] など任意の深さのテストをすべき。
044 の対処で、Core 言語の仕様を変更、Literal には Type じゃなくて Qual Type をつけるようにした。
…のだが、それに関連するところを直していたら、DictPass.tyScrut の以下の箇所が怪しい:
altty (LitAlt l, _, _) = return $ case l of LitInt _ ( _ :=> t) -> t LitChar _ ( _ :=> t) -> t LitFrac _ ( _ :=> t) -> t LitStr _ ( _ :=> t) -> t
述語すててはまずいケースあるのでは。
044 のついでにつくった、整数のみの defaulting では、sqrt 2 とかがダメなのは確実。 defaulting がカバーすべきケースをきちんと理解したころに、045 に取り組もう。
ノートの p.167 に以下のように書いている。
(STG の) case 式はいつも正格である。たとえ DEFAULT alternative ひとつのときでも。 (これは Haskell と違うところ。)よって、case error "urk" of { DEFAULT -> True } は error となる。
Haskellでは同様の式は True
たしかに、そうだ:
Prelude> case undefined of { _ -> True } True
めも:
ノート p.167 には、case binder についても記載あり。今の実装、case binder つかってる?? ⇒ つかってないはず。Haskell からの変換ではでてこないだろうから。いったん取り除いてもよいのかもしれない。
PreDefined.hs にて、primConsName 以外に、いっこだけ primNames に入ってるの、なんだろ? (わけた意図とか)
-- Primitive Names primNames :: Table Id primNames = fromList (primConsNames ++ [ ("putStrLn", "Prim.putStrLn") ])
Prim.() は、とりあえず Prim.() でいいかな。 なにを Prim にいれて、なにを Prelude にするかは、どこかで明確に設計方針を整理しよう。
インスタンスのメソッド定義は、すべて explicit typed にできて、そうすべきだった。 そうでなくては、特殊化された関数として後続(辞書渡し変換)で処理できなかった。
RenUtil.renameVar では、すでに qualified かどうかで処理をわけたが、判定がその場しのぎすぎる。
Absyn.RecTy ってなんだっけ…ああ、レコード型か(かな?)