为什么传递Int,其中F [_]参数预期有效?

Art*_*hou 14 scala higher-kinded-types

假设我们有一个功能:

def bar[F[_], A](x: F[A], y: F[A]) = null
Run Code Online (Sandbox Code Playgroud)

以下所有行为都很明确:

bar(List(1, 2, 3), List(1)) // compile ok
bar(List(1), Some(1)) // doesn't compile
Run Code Online (Sandbox Code Playgroud)

但,

bar(1, List(1)) // compile ok
bar(1, 1) // compile ok
Run Code Online (Sandbox Code Playgroud)

为什么?

来自FSiS第1部分的 PS示例- 类型构造函数,函数和种类投影仪

Sha*_*nds 4

我认为以下给出了线索​​(尽管仍然存在一些谜团):

def baz[F[_], A](x: F[A]): F[A] = x

scala> baz("str")
res5: Comparable[String] = str

scala> baz(1)
res6: Any = 1

scala> class Foo
defined class Foo

scala> baz(new Foo)
<console>:15: error: no type parameters for method baz: (x: F[A])F[A] exist so that it can be applied to arguments (Foo)
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Foo
 required: ?F
              baz(new Foo)
              ^
<console>:15: error: type mismatch;
 found   : Foo
 required: F[A]
              baz(new Foo)
                  ^

scala> case class Foo2
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined class Foo2

scala> baz(Foo2)
res10: scala.runtime.AbstractFunction0[Foo2] = Foo2
Run Code Online (Sandbox Code Playgroud)

因此,函数barbaz正在寻找它们可以匹配的任何容器类型(Comparable对于 String、AbstractFunction0对于 case 类等)以匹配预期F[_]

推测:在 的情况下Int,我怀疑我们正在为底层字节码中的(装箱的)原始类型找到一个特殊的“容器”类型。如果这个特殊类型只能作为“ Any”打印回 Scala,但实际上是我们可以认为是“ Any[_]”的某种特殊类型,那么就可以解释我们看到的结果。作为这与基元的特殊处理有关的佐证,请注意,它对于非基元简单类型(如Foo上面的(非大小写)类)失败。