为什么foo [F [_],A](ff:F [A])接受foo(1)?

时间:2016-01-17 13:06:43

标签: scala type-constructor

为什么对foo(1)的调用在我的Scala 2.11.7 repl中有效,如下所述?

scala> def foo[F[_], A](fa: F[A]) = null
foo: [F[_], A](fa: F[A])Null

scala> foo(List(1))
res0: Null = null

scala> foo(1)
res1: Null = null

我对foo(1)的调用中的参数不是类型构造函数,那么为什么Scala repl会接受它呢?

2 个答案:

答案 0 :(得分:3)

您的Int被视为类Any的实例(因为它不是类型构造函数,因此分析类型层次结构以查找也是类型构造函数的超类型),并且类{{1在Scala中,它被认为是Any类型的类型构造函数。

您可以使用以下代码检查此行为:

Nothing

输出:

import scala.reflect.runtime.universe._

object Main {
  def foo[F[_], A](fa: F[A])(implicit ev: TypeTag[F[A]], ev2: TypeTag[A]) = {
    println(ev)
    println(ev2)
    println(ev.tpe.typeArgs)
    println()
    null
  }

  def main(args: Array[String]){
    foo(List(1))
    foo(1)
  }
}

答案 1 :(得分:0)

foo(1)之所以有效,是因为存在从int2Integerjava.lang.Integer的隐式转换

foo(int2Integer(1))

IntegerComparable[Integer]

的实例
public final class Integer extends Number implements Comparable<Integer>

我们看到的Comparable确实是类型构造函数。例如,我们可以reproduce像这样的相同行为

def foo[F[_], A](fa: F[A]) = 42
trait Bar // not a type constructor
implicit def barToComparable(b: Bar): Comparable[Int] = (o: Int) => -1
val bar = new Bar {}
foo(bar) // OK due to implicit conversion barToComparable