読者です 読者をやめる 読者になる 読者になる

osiire’s blog

ふしぎなそふとやさん

構造的部分型の比較

私はOCaml, haXe, Scalaを勉強してきましたが、この三つの言語では構造的部分型がサポートされています。せっかくだから三言語の構造的部分型の特徴を比較してみることにしました。

  • OCamlは全て型推論してくれる代わりに部分型への変換は明示的。部分型変換ができるバリアントがある。
  • haXeは全て型推論してくれて、かつ部分型への変換も暗黙的にできるけど、場合によってはコンパイルがとまらない
  • Scala型推論は(完璧には)してくれないけど、部分型への変換は暗黙的

全部違うのが興味深いですね。ところで、それぞれの型の表現も比べてみましょう。

(* OCaml版 *)
# type t = [ `Const | `Var ];; (* 多相バリアント *)
type t = [ `Const | `Var ]
# type tt = [ t | `Exp ];;
type tt = [ `Const | `Var | `Exp ]
# let cor x = ( x : t :> tt );;
val cor : t -> tt = <fun>
# type o = < name : string >;; (* 多相レコード(オブジェクト) *)
type o = < name : string >
# type oo = < name : string; age : int >;;
type oo = < name : string; age : int >
# let cor x = ( x : oo :> o );;
let cor : oo -> o = <fun>
// haXe版
typdef NamedT = { // name関数があるもの
  function name() : String;
}
class Person { // Personクラスはname関数を持っている
  public function new() { }
  public function name() { return "osiire"; }
  public function age() { return 20; }
}
class Test {
  public static function main() {
    print(new Person()); // NamedT型が要求される場所にPerson型を入れて呼び出し
  }
  public static function print( n ) { // name関数があればいい
    trace(n.name());
  }
}
  //scala版
  object Test {
    def main( args : Array[String] ) = {
      print( new { def name() = "osiire"; def age() = 20 } ) // name関数とage関数を持つオブジェクトを生成
    }
    def print( n : { def name() : String } ) = { // name関数があればいい
      println(n.name())
    }
  }

Scala版で{ def name() : String }の部分を別名にしたかったのですが書き方がいまいちわからず。