Scalaといえば今週問題になったdef id[A]=(x:A)=>x のもとで id(id)(1) がまともに型推論されないのは何故なんだろう。Scala力低い
2011-11-27 09:52:05いまいちlocal type inferenceがよくわからなかったのでメソッドならうまくいくかもと思い def ap[A,B](f:A=>B,x:A) : B = f x として ap(id, 1) と試したがやはり型推論がうまくいかない。 なるほど、まだわからん
2011-11-27 10:53:416.26.4 Local Type Inference, Case 3. Methods の 2番目のスキームに落ちて全てNothingに推論されている感じはあるのだけど、なぜ1番目の、「型パラメータを定数として扱い引数を型付けする」が失敗してるのか。まあいいや、またこんど
2011-11-27 11:07:47一つ目の例を見たらわかった… id(id) とした時点で外側のidの型引数が固定され、そいつのlower boundがないせいで内側の id の型引数が Nothingに固定されてしまうのか。型変数のまま上に伝播するわけではないのね。
2011-11-27 11:18:40生成された型変数が上に伝播せず、その場で制約を満たす具体的な型にinstantiateされる(っていったらいいのか何なのか)のはトップレベルに限った話ではないのだな
2011-11-27 11:39:01@keigoi 目的が推論の規則の話なので、求めてるものでないと思いますが、似たような関数でも def ap[A,B](x:A)(f:A=>B) = f(x) ってやると推論できます・・・というか、こうしないと推論されないですねたしかに #Scala
2011-11-27 11:43:56@xuwei_k ですねー。その場合 xに来るのはほとんどの場合単相なので普通に(?)推論されそうです。でもNilとかだとやはり引数型がNothingに落ちますねきっと。
2011-11-27 12:02:06@keigoi 一言で言うと、型パラメータの推論にあたっては、引数リスト(()で囲まれた部分)に関して、前から順に「引数リスト毎に」推論を行っているからです。
2011-11-27 12:45:09@keigoi と、これだけだとわかりにくいと思いますので、もうちょっと突っ込んだ説明をば。 まず、id(id) の時点っで、引数として渡されるidはメソッドなので、関数への自動的なconversionが入ります。ご存知の通り(?)、Scalaでは「関数の値」は多相になれないので
2011-11-27 12:46:38@keigoi 多相的じゃないなんらかの関数値に変換する必要があります。問題は、Scalaの現時点での型推論方式では、先ほど言ったように、「前から 順番に」引数リストを見て、型パラメータを確定させるので、A = Intという置き換えがその時点ではできないことです。
2011-11-27 12:48:06@keigoi というわけで、Scala処理系はその時点でAを何にしたら良いかわからないので、うまく推論できないときのデフォルト推論結果として、 A = Nothingにしてしまいます。もちろん、その後の適用を見れば、 A = Intであることはわかるのですが
2011-11-27 12:49:33http://t.co/3OGbsoQ1 なぜこれが動くのかわからなかったんだけど、http://t.co/6aFczR9W 引数リストの推論中にA,Bの関係が確定できるからなのかな
2011-11-27 12:55:14@kmizu とんでもない!理解がとても深まりました、部分式の型パラメータを確定させてからそのメソッド呼び出しの型を確定させるってことですね。
2011-11-27 13:34:59@keigoi はい。もちろん、この推論方式ははっきり言って「賢くなく」て、Scalaの型システムの根本的な限界はあるにせよ、もうちょっと「賢い」型パラメータの推論はできると思います。ただ、中途半端に賢くすると、推論ルールがわかりにくくなる、というトレードオフはあるかなあと。
2011-11-27 15:06:03@keigoi Oderskyらの研究者がそういう事を知らないわけが無いので、意図的にその辺は弱く(推論方法を単純化)してあるのだろうと思ってます。
2011-11-27 15:07:36@yasushia @keigoi それが動作する理由はまた少し違いまして。Scala 2.8でimplicit推論ルールが追加されたことによるものです。端的に言うと、implicit引数の一部の型が未確定なときに、確定している型から逆方向に型パラメータを推論するルールです。
2011-11-27 15:52:46@yasushia @keigoi 具体的には、このケースではimplicit parameterが渡される前にAの型パラメータがインスタンス化されて、それを元にimplicit parameterに使われている型パラメータBが推論されます。ちょっとややこしいですが。
2011-11-27 15:54:25@kmizu まだちょっとよくわかってないんですが、最初のmagicの場合ではA,Bが同時に決定(インスタンス化?)しなければならないからBがNothing、implicitだとAとBの決定に時間差ができて、みたいな感じでしょうか。
2011-11-27 21:09:52@yasushia だいたいそんな感じです。インスタンス化、という用語は、型パラメータに対して具体的な型を当てはめるときにしばしば使われる用語ですが、あまりなじみが無いかもしれません。ちょっとテキトーな説明を書いてみました。 http://t.co/KKdnqDmK
2011-11-27 21:33:12