2016-03-18 12 views
1

これはうまくいくと思いました。私は間違ったことをしていますか?ラムダ計算:Scalaで適用

val apply = (f: Any => Any, v: Any) => f(v) 
val square = (x: Int) => x * x 

私は(正方形、10)を適用する想像は100

ことになる。しかし、私はエラーを取得する:

:15: error: type mismatch; 
found : Int => Int 
required: Any => Any 
     apply(square, 100) 

私がここで行方不明ですか?

答えて

3

関数は戻り値の型は共変ですが、引数は反例です。 Int => IntInt => Anyのサブクラスですが、Any => IntまたはAny => Anyでは使用できません(たとえば、Stringパラメータが渡されたコンテキストで使用でき、処理ができない場合があります) Int)。

Cosiderこの:Int => IntAny => Anyのサブクラスである場合

val foo: Function[Int, Int] = { x => x * x }  
def bar(f: Any => Any)(arg: Any): Any = f(arg) 

bar(foo)("foo") //??? 

ザ・、そして最後の行は有効になります。しかし、Stringパラメータでfooが呼び出されることになります。

Any => Intは、Int => Intのサブクラスです(前者が必要な場合はどこでも使用できます)。これは "反変"の意味です。

+0

追加してください: 'apply apply'の定義を' def apply [T] =(f:T => T、v:T)=> f(v) 'に変更すると、このように、v、fの入力とfの出力の型は同じ型であることが分かっているからです。 –

+0

@TzachZohar 'apply [Any]'と 'apply [Int]'は本質的に2つの異なる関数であるため、「同じ型であることがわかっている」ためではありません。この場合。 – Dima

+0

@Dima、関数が引数に反例がある場合、Any => IntはInt => Intのサブクラスであると言うことができますか? –

関連する問題