为什么 A => String 与 _1.type => String where val _1: A 不同?

Why is A => String not the same as _1.type => String where val _1: A?

在此 Scala 2.13 示例中:

import scala.language.implicitConversions

object Main2 extends App {

  trait Foo {
    type F = this.type => String
  }

  def fooA[A <: Foo](f: A#F, toString: A#F => String): String = toString(f)
  def fooB[A <: Foo](f: A#F, toString: (A => String) => String): String = toString(f)
}

它失败了:

type mismatch;
 found   : _1.type => String where val _1: A
 required: A => String
  def fooB[A <: Foo](f: A#F, toString: (A => String) => String): String = toString(f)

为什么 A => String_1.type => String where val _1: A 不一样?

f.asInstanceOf[(A => String)]安全吗?

是否有一个具体的例子表明这不起作用?

一个不起作用的具体例子:

def fooB[A <: Foo](f: A#F, toString: (A => String) => String): String = ???

trait X extends Foo
trait Y extends Foo

def ok(f: X#F, toString: (Y => String) => String) = fooB(f, toString)

这会编译,因为编译器将类型参数 A 解析为 Foo。但是 f 显然不是 toString 的有效参数。

我想你误解了什么是this.type。来自 scala 2.13 spec:

Every value in Scala has a type which is of one of the following forms. A singleton type is of the form p . p.type. Where p p is a path pointing to a value which conforms to scala.AnyRef, the type denotes the set of values consisting of null and the value denoted by p p (i.e., the value v v for which v eq p)

这意味着 this.type 对于 Foo 的每个实例都是唯一的。在 fooB:

def fooB[A <: Foo](f: A#F, toString: (A => String) => String): String = toString(f)

编译器发现您试图传递 f 类型是:

(some object of A which upper-bouned by Foo).type => String

function from singleton-type object to String into function 什么函数从 A 类型的对象到 String.

注意类型Anew A())的对象与(new A()).type的类型不同,它们有不同的类型,这是编译器显示错误的原因。

例如,你可以写类似的东西,它会编译:

class Bar extends Foo {
  def conversion: this.type => String = b => "bar"
}
def someStringConversion[A <: Foo]: A#F => String = ???
val bar: Bar = new Bar
someStringConversion[Bar](bar.conversion)
val conversionType: bar.type => String = bar.conversion
val customConversion: bar.type => String = (x: bar.type) => "some string"
someStringConversion[Bar](customConversion)

因为 bar.typethis.type 具有相同的类型(它们都指的是一种单例类型 - bar.type

结论

你的函数 fooAfooB 有不同的签名,A#F => StringA => String 不一样,你不能先用 asInstanceOf . fooB 不适用于 Foo 的任何实例,因为任何 Foo 实例都有自己的 this.type 单例类型。它与 Foo 无关,而某些 Foo 实现与 Foo.

相关