1

抽象関数/メソッドのタイプに基づいて、実装メソッドの正当な戻りについて効果的にアサーションを作成できるようになりました。以下のコンパイラの動作(ほとんど)は理にかなっていると直感的に感じますが、なぜそれを主張できるのかを明確に説明していただければ幸いです。

def f[T](t: T): T  

恒等関数にすることしかできません(クラスEもコンパイルすることを除いて)。Tは有界ではないので何も知らないことは理解できますが、その説明にはギャップがあります。「foundscala.Int(42)requiredInt」を報告するコンパイラーは私を光に近づけていません。

trait A{ def f[T](t: T): T }
// compiles
class B extends A{ override def f[Int](t: Int): Int = t }
// does not compile
class C extends A{ override def f[Int](t: Int): Int = t + 1 }
// does not compile
class D extends A{ override def f[Int](t: Int): Int = 42 }
// compiles
class E extends A{ override def f[Int](t: Int): Int = 42.asInstanceOf[Int] }
// compiles
class F extends A{ override def f[Int](t: Int): Int = identity(t) }
4

3 に答える 3

1

質問の他の部分にはまだ誰も答えていないので:

一般に、この性質はパラメトリック性と呼ばれ、そこから得られる保証は自由定理と呼ばれます。ところで、これはタイプケース (およびマークされていない副作用) を無視する場合にのみ保持されるため、Scala の大部分はカウントされません。

于 2012-11-26T16:56:49.080 に答える
1

Jesper は、主な質問に対する正しい答えを持っています: [Int]is not fill in a type of Intfor T、紛らわしい名前の新しいジェネリック型パラメーターを作成していますInt

しかし、私は補遺もあります:

実行時に有効であっても、ユーザーが卑劣なことをしないことを少し信頼しすぎています。

def f[T](t: T): T = (t match {
  case i: Int => -i
  case s: String => s.reverse
  case b: Boolean => !b
  case o: Option[_] => None
  case s: Seq[_] => throw new Exception("Ack")
  case _ => t
}).asInstanceOf[T]

正確にはアイデンティティ関数ではなくなりましたね。一致や例外などを禁止する場合asInstanceOf、それは ID でなければなりません。

于 2012-11-26T14:58:37.843 に答える