# 未分類メモ [↑up](bunny_notes) 個別に issue を立てようとすると間に合わない、こまごましたメモを以下に。 ## 2020-11-18 [これ](https://uhideyuki.sakura.ne.jp/studs/index.cgi/ja/thirtydays2release09#2020-11-18p0) 実際に修正するときには、issue 発行してからにしよう。 ## 2020-11-17 0.9 版には、defaulting をちゃんとするのは間に合わなさそう。 その場合、いまは、型検査では ${default (Integer, Double)} を前提にして、 後段の DictPass では Integer への defaulting しかサポートしていないという非対称は取り除いておきたい(つまり、型推論は ${default (Integer)} で行うようにすればいいのではないかと思っている)。 0.9 版のコード名は basecamp でいいのではないだろうか。 ## 2020-11-05 [114](bissue114) では、Desugar 時に生成した変数名がプログラム中の変数と衝突してバグっていた。同様の問題がないか、また、変数名の生成規則に一貫性があるか、チェックしたい。 ## 2020-10-18 Version 0.9 (code name : learning by imitation (見様見真似)) をリリースしたら、 bissues をすべて印刷しよう。2up 両面にすれば、そんなに大量にはならないはず。 セブンイレブンのネットプリントなどでも、両面印刷はできるようなので。 PDF の連結は…めんどうだけど手作業になるかなぁ。 ## 2020-10-07 test/samples/sample285.hs (fromrational.hs) などで、 まだ浮動小数点数リテラルをサポートしていないので、割り算を書いているのだけど、 さらに型注釈をつける必要がある。defaulting 未実装なためだと思っているけど、 要確認。(defaulting 実装後のテストで) $$
{
x = toRational (314/100 :: Double)
y = toRational (10/3 :: Double)
$$}

## 2020-10-06

今日 Types.hs に追加した tRational は次のようになっている:

$$
{
tRational :: Type
tRational  = TAp (TCon (Tycon "Prelude.Ratio" (Kfun Star Star))) tInteger
$$}

これは、いま一時的に Ratio 定義を lib/Prelude.hs に書いているためだが、
これを Data.Ratio に移動したときには、上記の tRational も変える必要がある。

## 2020-06-08

instance declaration を scan するときに、左辺の関数名を qname として登録しないための
[仮対処](https://uhideyuki.sakura.ne.jp/studs/index.cgi/ja/bissue078#2020-06-08)  
がイマイチ。

## 2020-06-06

どどっとテスト追加

- testcases/map.hs: sample240
- testcases/until.hs: sample241
- testcases/undef2.hs: sample242
- testcases/null.hs: sample243
- testcases/listindex.hs: sample244
- testcases/length.hs: sample245
- testcases/lastinit.hs: sample246
- testcases/concat.hs: sample247
- testcases/astypeof.hs: sample248
- testcases/scanl.hs: sample249
- testcases/scanl1.hs: sample250
- testcases/foldl1.hs: sample251
- testcases/scanr.hs: sample252
- testcases/scanr1.hs: sample253
- testcases/iterate.hs: sample254
- testcases/replicate.hs: sample255
- testcases/cycle.hs: sample256
- testcases/drop.hs: sample257
- testcases/splitat2.hs: エラーする。
- testcases/splitat.hs: sample259
- testcases/takewhile.hs: sample260
- testcases/dropwhile.hs: sample261
- testcases/span.hs: sample262
- testcases/break.hs: sample263
- testcases/words.hs: sample264
- testcases/reverse.hs: sample265
- testcases/lines.hs: エラーする
- testcases/lines2.hs: sample267
- testcases/getchar.hs
- testcases/getline.hs
- testcases/andor.hs: sample268
- testcases/anyall.hs: sample269
- testcases/elemnotelem.hs: sample270
- testcases/lookup.hs: sample271
- testcases/sumproduct.hs: sample272
- testcases/maximumminimum.hs: sample273
- testcases/zipunzip.hs: sample274
- testcases/pseq.hs: sample275
- testcases/seq.hs: sample276

入力のあるテストをする仕掛けはまだない。

### けねん

${x `seq` f x} としたとき、いまの実装でも確かに先に x が評価されるが、
その評価された x が、ちゃんと f に渡されるんだろうか。評価前を指したままになっていないだろうか??

## 2020-06-03

- 100 桁制限とか(Linux のコードが 80桁制限だったのを 100桁に緩和したと聞いて)

## 2020-06-01

ddumpAssump と ppTypes などは1つのファイルにまとめたら。

## 2020-05-26

- normQTy と同じ処理を TrCore でも使いたくなってコピペ。共通してもちいる Core.hs に移すか。その際には、もっとまともな実装にしたい。
- _fail# の型、量化したほうがいいような気がしたんだけど、するとエラーした。理解が浅い:

$$
{
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
$$}

## 2020-05-23

- normQTy で head をつかっている部分が気になる。Pred に含まれる tv は高々ひとつ?
- tcBind がモナドになっていないのは無理があるか(のちにシンプルに戻したので、別にいいかも)

## 2020-05-19

Rename.renRhs (A.GuardedRhs .. にて、

$$
{
-- todo cnvGs support most simple case that has only one statement.   
$$}

## 2020-05-16

I set up Ubuntu on a desktop PC that I have but unused.
So, I record the additional packages necessary to build bunny .

- -XNoMonadFailDesugaring
- Text.PrettyPrint.ANSI.Leijen: cabal ansi-wl-pprint
- Options.Applicative: cabal install optparse-applicative

In addition, I had to install jdk, sudo apt install openjdk-14-jdk

w3m を入れたので、Emacs で書ける。(「書ける」がなかなか出て来ない感じ、なつかしい)

## 2020-05-15
### DefaultClause 不要?

[035を修正した](https://uhideyuki.sakura.ne.jp/studs/index.cgi/ja/bissue035#2020-05-15p2)
のだが、やや考えていたのと事情がちがった(←のリンク先にすこし目盛った)。
のと、これだと、Case の DEFAULT 節は未使用ってことになるのかな。
本当にいらないのなら削る。

## 2020-05-12
[今日の修正](https://uhideyuki.sakura.ne.jp/studs/index.cgi/ja/bissue067#2020-05-12p0)
は、
${filter (\pr -> head (tv pr) `elem` tv t') }のあたり、
pr (Predicate) の tv が一つであることを決めつけたような実装がいまいちだし、
また、DictPass でも似たような簡略化をしていたような気がする。全体的に、要整理。
(ちゃんとコンパイラが仕様を満たすようになってからでいいとは思うが)

DictPass.normQTy も、これでいいのか、とか、必要なのかは、
いずれ統計(normQTy の中に、処理前後で変わるのかとか、head (tv pr) で
すてられる情報などを吐き出させる)をとって調べたい。

## 2020-05-11
sample191.hs のエラーのしかたはいまいちな感じ。qname not found ## 
となって、それ自体は正しい。つまり、${a ## b : bs = ... } は 
${(a ## b) : bs = ... }
と解釈されたわけで、ここでは Main.: が再定義されたわけだけど、再定義していいのか
(いいのかも)、および、じゃあ ## はコンストラクターパターンにみえたのか?
(よくなさそう)

## 2020-05-10
- renDecls 内の removeInfix は、きちんとつくって、複数の箇所から再利用できそう。 ⇒ scanDecls 内に移動 ([070](bissue070))

## 2020-05-09

- where @qr(q, r) = quotRem n d のように書けなかった
- 関数の引数にこの形のパターンが現れることもある

## 2020-05-08

- ひとつの識別子に対して、2つ以上型注釈を書いてしまったらどうなる(現状の実装、および、仕様の両方を確認)

## 2020-05-06

- ランタイムにおいて、(+) やら (*) やらの計算の結果は、LitInt などじゃなく、HeapObject (BoxedIntObj etc) ではあかんのだろうか?
- もしそれでいいなら、LitInt は不要になるかな(生の整数リテラルは Integer), … Literal は比較が可能なのか。STG の意味論要確認。
- 元の STG の設計を踏まえると、BoxedHogeObj のなかみは、ランタイムにおける生のオブジェクトにすればいいように思われる。(いま LitHoge にしているのが重いような…)

- [056](bissue056) の対処で、Main.main の型を制約するために追加したダミー関数 (main#) はコードを出力する必要がない(しても害はないので、いまはしている)

- 追記: main# 出力の削除は、個別対処ではなく、未到達コードの削除という一般的な形で実現したい。

## 2020-05-05

### Java FFI?
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 の範囲外?

### unsafe

unsafePerformIO は欲しくなるかも。trace はそれで実現するとか、
上で書いたように、Java FFI の多くが IO になるなら(大丈夫な場合に)unsafePerformIO で純粋化するとか…

### FFI memo 2

FFI は、ccall なみに単純にしたい。ポインタが全部 JObject では困ってしまいそうなので、
コンストラクタの出力は、そのクラスのポインタということにできないかな。

少なくとも、以下の種類がいりそう

- jnew : Java クラスのオブジェクト生成
- jmethod : メソッド(第1引数にレシーバ)
- jsmethod : スタティックメソッド
- jfield: メンバ変数
- jsfield: スタティックメンバ変数

field という名は、[Declaring Member Variables](https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html) より:

There are several kinds of variables:

- Member variables in a class—these are called fields.
- Variables in a method or block of code—these are called local variables.
- Variables in method declarations—these are called parameters.

$$
{
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 の例は、すぐにでも出来そうでは。

コールバックとかは、どうすんのかなぁ…。

### Generator

[1..n] や [1..] などは、Haskell Language Report の3章でもうすぐでてくるが、
Enum をきっちり作ってからのほうが、たぶん、いい。

### その他メモ

- lib/Prelude.hs の take は、なんとなく language report と違う書き方にした。同じでもいける?
- succ, pred :: a -> a のようにまとめて書けるんだったっけ?


## 2020-05-04

--ddump-absyn で表示されるやつは、fixity resolution 前なのかな?


## 2020-04-27

Rename.renInstDecls 改造中。

lookupKdict qcn とやって、クラス名で kind を引くのはいいとして、
どうやってこれを登録したのか覚えていない。要確認。

ghci に聞くと、こんな感じ:

$$
{
Prelude> :k Show
Show :: * -> Constraint
Prelude> :k Monad
Monad :: (* -> *) -> Constraint
$$}


## 2020-04-25

Show の実装に関して。

(1, "abc", ["a", "b", "c"]) などでテストすべし。

その前に(Pair の前にリスト)、["a", "b", "c"] や [["a", "b"], ["c"], [], ["d", "e"]] 
など任意の深さのテストをすべき。

## 2020-04-22

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 に取り組もう。

## 2020-04-20

ノートの p.167 に以下のように書いている。

(STG の) case 式はいつも正格である。たとえ DEFAULT alternative ひとつのときでも。
(これは Haskell と違うところ。)よって、case error "urk" of { DEFAULT -> True }
は error となる。

Haskellでは同様の式は True

たしかに、そうだ:

$$
{
Prelude> case undefined of { _ -> True }
True
$$}

めも:

- seq は、Prim.seq として、STG の case 式をつかった定義にすればよさそう(Core 以前では定義できない)
- case undefined of { _ -> True } は testcase に加えておきたい

ノート p.167 には、case binder についても記載あり。今の実装、case binder つかってる??
⇒ つかってないはず。Haskell からの変換ではでてこないだろうから。いったん取り除いてもよいのかもしれない。

## 2020-04-19

PreDefined.hs にて、primConsName 以外に、いっこだけ primNames に入ってるの、なんだろ?
(わけた意図とか)

$$
{
-- Primitive Names

primNames :: Table Id
primNames  = fromList (primConsNames ++
                       [ ("putStrLn", "Prim.putStrLn")
                       ])
$$}

Prim.() は、とりあえず Prim.() でいいかな。
なにを Prim にいれて、なにを Prelude にするかは、どこかで明確に設計方針を整理しよう。

## 2020-04-18

インスタンスのメソッド定義は、すべて explicit typed にできて、そうすべきだった。
そうでなくては、特殊化された関数として後続(辞書渡し変換)で処理できなかった。

RenUtil.renameVar では、すでに qualified かどうかで処理をわけたが、判定がその場しのぎすぎる。

Absyn.RecTy ってなんだっけ…ああ、レコード型か(かな?)