ScalaのHigher-kind Genericsについて
@pomu0325 なるほど。えーとですね、trait AttrHelper[+Holder[X]]のHolderってのはクラスそのものじゃなくて、「型パラメータを引数に取る何か」(通常、型コンストラクタと呼ばれます)を表す仮引数みたいなものなのです。(続く) #scala
2010-04-29 14:16:24@pomu0325 で、Holderの実体はAttrHelperのユーザ(サブクラス含む)が与えます。先ほどの例では、Holder = Boxとして、HolderにBoxが束縛されているわけです。 #scala
2010-04-29 14:18:09@pomu0325 あ、ちょうど行き違いだったようです。すいません。その通りで、型パラメータ名(のようなもの)です。Holder自体は型じゃないので、Javaのジェネリクスとかにおける通常の型パラメータとは少し違いますが。
2010-04-29 14:19:46@kmizu あー、すいません行き違いで。詳しい解説ありがとうございます。正確にはなんて呼ぶのでしょうか?→型パラメータ名
2010-04-29 14:21:36で、[+Holder[X]]という部分だけど、ここが問題。通常のジェネリクスでは[G]あるいは[+G](covariantな場合)のようになるけど、[G[X]]のような形になっている。 #scala
2010-04-29 14:23:13ここで、Holderは「型」ではなく、「ある型Xを型パラメータとして取って何かの型を作り出すもの」を表している、というのがポイント。関数の型っぽく書くと、* -> *みたいな。型を取って型を返す関数、のようなもの。 #scala
2010-04-29 14:25:28つまり、AttrHelper[何か]の何かには通常の型(String,Intとか)は与えられなくて、「型を取って型を返す関数」のようなものしか与えられない。 #scala
2010-04-29 14:27:01Listとかは、一つの型(String,Intとか)を引数に取って、別の型(List[String]とかList[Int])を返す関数のようなものとして見ることができるので、AttrHelper[List]みたいに書くことができる。 #scala
2010-04-29 14:29:08あくまでAttrHelper[List]であって、AttrHelper[List[String]]とかじゃないのがポイント(List[String]だと普通の型になっちゃうので)。 #scala
2010-04-29 14:29:59@kmizu カタカタ「飲んどる場合かーッ」by jojo
2010-04-29 14:30:37このような、「型を受け取って型を返す何か」みたいなものを型コンストラクタと呼びます。ListとかArrayとかMapとかは全部型コンストラクタです。 #scala
2010-04-29 14:30:58ちなみに、Javaのジェネリクスでも、java.util.Listとかjava.util.Mapとかは型コンストラクタなのですが、JavaではScalaのような高階のジェネリクスが無いので、意識する機会が無いのです。 #scala
2010-04-29 14:32:55@pomu0325 Scalaの言語仕様書では型コンストラクタパラメータ(type constructor parameter)と呼んでいますね。他に一般的な呼び方も知らないので、とりあえずそんな感じで。 #scala
2010-04-29 14:35:47@kmizu カリー化みたいなことはできるんでしょうか? Mapの場合は、Hoge[+G[X,Y]] に Moge[Map] みたいに数合わせないとですよね? Hoge[G[X]]にMoge[Map[String, _]] みたいなイメージ。
2010-04-29 14:36:52@pomu0325 カリー化をサポートするには、型コンストラクタに型パラメータを渡した結果がまた型コンストラクタになる、みたいなのが表現できないといけないのですが、これは現在のScalaの型システムでは表現できません。 #scala
2010-04-29 14:41:34@pomu0325 ただし、カリー化でなく部分適用なら実は抽象型を型エイリアスを組み合わせればエミュレートすることができて、実際、そんなライブラリを作ってた人が居ます(ページは忘れましたが)。 #scala
2010-04-29 14:42:34@kmizu なるほど。うーん。Scalaジェネリックスはかなりの変態ですな。たぶん、う”、何だこれってならなくなりました。
2010-04-29 14:42:37@h_sakurai 変態かと言われると、概念的には割と自然な拡張かなと個人的には思います。ちなみに、Haskellも同様の概念をサポートしています(OCamlは確か無かった…はず)。 #scala
2010-04-29 14:47:00