Help us understand the problem. What is going on with this article?

構造的部分型について

More than 5 years have passed since last update.

Structural Subtyping とは - いげ太のブログ

structural subtyping (構造的部分型)とは、強い型付けによる恩恵は魅力的やな、でも型は定義しても継承関係までは定義したくない、制限による堅さに利はあるけど柔軟性を失いすぎるのもちょっとな、インターフェースばっかりいくつも定義するのもアホらしいし、その時々で適当なインターフェース割り振るようにしたらステキやん、というシグネチャ至上主義だ。

構造的部分型の比較 - まぁ、そんなもんでしょう

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

Scalaの構造的部分型

http://www.ne.jp/asahi/hishidama/home/tech/scala/type.html

// クラスAとBには継承関係は無い
class A {
  def zzz() = println("aaa")
}

class B {
  def zzz() = println("bbb")
}
scala> var z : { def zzz() } = _
z: AnyRef{def zzz(): Unit} = null

scala> z = new A
z: AnyRef{def zzz(): Unit} = A@61064425

scala> z.zzz()
<console>:9: warning: reflective access of structural type member method zzz should be enabled
by making the implicit value scala.language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import scala.language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scala docs for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
              z.zzz()
                ^
aaa

上の警告は

$ scala -language:reflectiveCalls

で除ける。明示的に機能をオンにしないといけないのは、
リフレクションを使っていいよっていう許可を与えるため。

scala> class A { def zzz() = print("aaa") }
defined class A

scala> class B { def zzz() = print("bbb") }
defined class B

scala> val list = List[{ def zzz() }](new A, new B)
list: List[Object{def zzz(): Unit}] = List(A@f1da57d, B@194fad1)

scala> for(z <- list) z.zzz()
aaabbb
scala> def callzzz(x:X) = x.zzz()
<console>:7: error: not found: type X
       def callzzz(x:X) = x.zzz()
                     ^

scala> def callzzz(x:{def zzz()}) = x.zzz()
callzzz: (x: AnyRef{def zzz(): Unit})Unit

scala> callzzz(new A)
aaa
scala> callzzz(new B)
bbb

Xの部分を型推論させることはできないのかな?

HaXe

構造体(匿名オブジェクト)
http://haxe.org/manual/struct?version=17720

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());
  }
  public static function print( n ) { // name関数があればいい
   trace(n.name());
  }
}

結果

osiire

Personクラスがnameメソッドを持っていないとコンパイルエラー

class Person {
  public function new() { }
  public function age() { return 20; }
}
Build failure
Test.hx:10: characters 10-22 : Person should be { name : Void -> String }
Test.hx:10: characters 10-22 : Person has no field name
Test.hx:10: characters 10-22 : For function argument 'n'

OCaml

TypeScript

http://yaakaito.org/blog/2013/05/02/typescript-subtyping/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした