单抽象模式匹配的抽象参数参数化

时间:2017-09-25 21:36:56

标签: scala

如果有人能够在两个类型参数之间的奇怪演员中详细解释编译器的逻辑,我将非常感激

def testComposition[T](g: T=>T, n: Int): T => T = {
  ...
  helper(_,n)
}

可以执行

def unsafeCoerce[A, B]: A => B = {
  val a = implicitly[A =:= A]
  implicitly[B =:= B] match {
    case _: a.type => implicitly[A =:= B]
  }
}

为什么编译器允许隐式编译[A =:= B]?

此示例取自here

1 个答案:

答案 0 :(得分:1)

  

问题是为什么我们可以证明。我们无法证明String例如是Int,但可以证明隐式[B =:= B]是a.type

我们不能。 implicitly[B =:= B]a.type或者不是{(即implicitly[B =:= B] eq a为真,或者不是{0}}。代码说,基本上:

  1. 如果是,则它同时包含B =:= BA =:= A类型,因此AB相同(因为=:=是不变的,所以implicitly[A =:= B]编译。

  2. 如果不是,请抛出MatchError

  3. 请注意,第二种情况是完全可能的,并且它是tpEquals的安全定义所发生的情况,例如

    object =:= {
      implicit def tpEquals[A]: A =:= A = new =:=[A,A] {
        def apply(x: A): A = x
      }
    }
    

    事实上,正如我的评论所说,unsafeCoerce[String, String]("hi")一起发生,因为对implicitly的两次调用会创建两个不同的实例。