次の2行のコードを検討してください。
def foo[F[B],A](fa: F[A]): String = fa.toString
println(foo(10))
印刷し10
ます。どういうふうにコンパイルできるのかしら。Scalaがここでジェネリックを解決する方法を理解しようとしています。つまり、A、B、Fとは何ですか。
Intellijを見ると、10はScala IntからJava Integerに変換されているようです。しかし、Java IntegerがどのようにF [A]に変換されるのか(Java Integerはジェネリック型ではありません)は、foo
期待どおりにわかりません。
fooが受け取ることを想定しているJava IntegerからF [A](Java Integerはジェネリック型ではない)への変換方法。
Java Integer
はのサブタイプですComparable[Integer]
public final class Integer extends Number implements Comparable<Integer>
Scala 2.13推論F = Any
とA = Nothing
scala> def foo[F[_],A](fa: F[A]) = fa
def foo[F[_], A](fa: F[A]): F[A]
scala> foo(10) // print
foo[Any, Nothing](10) // : Any
scala> foo(10)
val res9: Any = 10
この推論は、暗黙の変換が存在するために発生します
implicit def int2Integer(x: Int): java.lang.Integer = x.asInstanceOf[java.lang.Integer]
この変換を非表示にすると、コンパイルされません
scala> implicit val int2Integer = null
val int2Integer: Null = null
scala> foo(10)
^
error: no type parameters for method foo: (fa: F[A]): F[A] exist so that it can be applied to arguments (Int)
--- because ---
argument expression's type is not compatible with formal parameter type;
found : 10
required: ?F[?A]
^
error: type mismatch;
found : Int(10)
required: F[A]
ただしint2Integer
、コンパイルしたという事実にもかかわらず、暗黙の変換は実際には行われませんでした(バグの可能性があります)。
scala> foo(10)
val res9: Any = 10
の代わりにとres9
入力する必要があった場所。Comparable[Integer]
Any
スカラ3(義母)推論F = Comparable
とA = Integer
の通り-Xprint:typer
foo[Comparable, Integer](int2Integer(10))
そして暗黙の変換が実際に適用されます
Starting dotty REPL...
scala> def foo[F[_],A](fa: F[A]) = fa
def foo[F[_$1], A](fa: F[A]): F[A]
scala> foo(10)
val res0: Comparable[Integer] = 10
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加