2016-05-03 7 views
0

Martin OderskyがScala-by-example(2014)で読んでいます。 61文字列からInt型への関数は、文字列Function1 [String、Int]のインスタンスとして と表されています。機能1は、以下のように定義される:このScalaサンプルのサブタイプ関数はどれですか?

trait Function1[-A,+B] {def apply(x: A): B}

それも言われ、さらにその

ダウン

S => TがSのサブタイプである '=> T'、S「は、のサブタイプで提供しますSであり、TはT 'のサブタイプである。

彼は、次のコード例を使用しています。 val f: (AnyRef => Int) = x => x.hashCode() val g: (String => Int) = f g("abc")

をだからここに私の質問をしてくださいです。 StringはAnyRefのサブタイプなので、この例ではfはgのサブタイプを表していると仮定しています。あれは正しいですか? その場合、その決定のロジックを説明してください。あなたの例を実行するのと同じ結果を与えるスカラ端末で次のコードを実行http://docs.scala-lang.org/tutorials/tour/variances.html

答えて

3

VUのサブタイプである場合には、VはどこでもそのU缶に立つことができます。

AnyRef => Intがある場合は、いつでもString => Intを使用できますか?はい! A StringAnyRefなので、渡すことができます。

したがって、はString => Intのサブタイプです。この関係(通常の「後方」の一種)は、関数が反例であると言うことで説明されます。引数にはがあります。

インスタンスfgは必ずしも関係がありません。しかし、彼らのタイプはそうです。

+0

yup。簡単でシンプルな - 意味があります。ありがとうございました! – TalBeno

0

FおよびG機能、および機能は、サブタイプおよび型パラメータのスーパータイプを可能にするタイプの分散を有します。 Int戻り、

val f = new Function[AnyRef /*or any supertype*/,Int /*or any subType type*/] { 
    def apply(x: AnyRef): Int = x.hashCode() 
} 

それはタイプAnyRefのパラメータに取る関数として定義される:

Gはとしての機能を実装することになるタイプ(AnyRef => INT)ののfuction、として宣言され。

gは、Stringを取り込み、Intを返す関数として定義されます。

val g = new Function[String /*Supertype of AnyRef*/, Int] { 
    def apply(x: String): Int = x.hashCode() 
} 

この場合、gは新しい関数ではありませんが、次のようになります。 gはfの別の参照です。本質的に、gはFunction[String, Int]にキャストされます。

編集:AnyValがintのサブタイプであるので、あなたもこれを行うことができます:

val gg: (String => AnyVal) = f 
関連する問題