by shigemk2

当面は技術的なことしか書かない

型パラメータの制約 その2

A <:< B

AはBと同じ、もしくはサブクラス。

scala> class Base
defined class Base

scala> class Ex1 extends Base
defined class Ex1

scala> class Another
defined class Another

scala>

scala> class Y[A] {
     |   def exec(implicit t:A <:< Base):Unit = println("exec")
     | }
defined class Y

scala>

scala> val y = new Y[Ex1]
y: Y[Ex1] = Y@50df89c9

scala> y.exec
exec

scala>

scala> val y2 = new Y[Another]
y2: Y[Another] = Y@6c7675ab

scala> y2.exec
<console>:13: error: Cannot prove that Another <:< Base.
              y2.exec
                 ^

A => B

可視境界の話。

Aは暗黙の型変換でBに変換できるというやつ。

下の例でいくと、指定したクラスはYクラスとして扱う、という制限がある。

なので、どこかでYクラスに変換しないとエラーになる。

もともとYクラスならば問題はない。

scala> class X
defined class X

scala> class Y
defined class Y

scala> class Z[A] {
     |   def exec(implicit t:A => Y):Unit = println("exec")
     | }
defined class Z

scala>

scala> val z = new Z[X]
z: Z[X] = Z@10d5d2dd

scala>

scala> z.exec
<console>:13: error: No implicit view available from X => Y.
              z.exec
                ^

scala>

scala> val z2 = new Z[Y]
z2: Z[Y] = Z@49f9655

scala>

scala> z2.exec
exec

scala>

scala> val z3 = new Z[X]
z3: Z[X] = Z@4b4a8192

scala>

scala> implicit def xToy(x:X):Y = new Y
warning: there were 1 feature warning(s); re-run with -feature for details
xToy: (x: X)Y

scala>

scala> z3.exec
exec