# ひとり Advent Calendar 2016 年 11 月 14 日

これは、[ひとり Advent Calendar 2016](hac2016) 7日目の記事です。

[前回](hac20161111)は、以下の2つに取り組む必要があると書きましたが、その続き。

1. インスタンスのメソッドをちゃんと多相として扱う
1. 「それ以外の多相関数(★未実装)」の扱い

まず、前者については、勘違いしていました。IO 向けに特殊化された (specialized) $<verb>{>>} は、
もう特殊化されているので、もはや多相関数ではありません。なので、これを単相扱いにしていたこと自体は正しいのでした。
つまり、これはたまたま動いていたのではなく、意図的にこのように実装したのを、すっかり忘れていただけでした。

ただ、ここでも微妙なところはあって、$<verb>{p >> q = p >>= \_ -> q} というように、$<verb>{>>} のなかで
$<verb>{>>=} を呼んでいるのですが、これを IO に特殊化された $<verb>{>>=} だと決めつけているところは、
難があるというか、まちがっていると思う。多相関数の specialization は、やるなら、もっときちんとやるべき。

ま、とりあえずは、このままでいきます。

というわけで、後者。辞書を受け取って、それを、他の多相関数に渡すような多相関数の扱いをやりました。

まず、こういった関数が、いくつの辞書を、どの順で受け取るのかについては、その関数の Qual Type における
[Pred] を見ればわかります。

[Pred] が空の場合は、単相関数なので、これまで通りの処理で OK。

[Pred] が空でない場合は、この [Pred] の要素数と同じだけの dictionary 変数を引数に取るので、
これを受け取るような Lambda 式で全体をくるんでやって、この Lambda の仮引数を適切に使うように
dictionary-passing style 変換してやればよかった。
(いまの私自身にしか通じなさそう$<fn>{自分でも、しばらくしてから読んだらわからなさそう。}な説明ですが)

あ、そうだ、↑これで動いてはいるんだけど、辞書を束縛する変数に TermVar を流用しているのは、いまいちかも。
ToDo に書いておこう。

ともあれ、以下のサンプルが動くようになりました。

$$<pre>{
f x y = x > y

s True = "True"
s False = "False"

main = do
  putStrLn $ s (f 100 10)
  putStrLn $ s (f 'x' 'y')
$$}

実行結果:

$$<pre>{
$ ./run test8d/Sample.java
True
False
$$}

あとは、tcExpr が網羅的でないのを、ちょびちょび補充していけば、完成に近づくんですかね。

それはそうと、DictPass というファイル名、あんまりイケてないなぁと思っていたんだけど、
タコっぽくてかわいいような気が、今日急にしてきました。