无法读取 REPL 返回的以下类型
def returnfuncdefGen[A] = (i: A) => i.toString.length
returnfuncdefGen: [A]=> A => Int
Run Code Online (Sandbox Code Playgroud)
虽然我明白
def returnfuncdefGen[A](i: A) = i.toString.length
returnfuncdefGen: [A](i: A)Int
Run Code Online (Sandbox Code Playgroud)
第一个版本是FP的作者简化(scala)调用coercing parameterize方法到函数中
人们究竟如何阅读这个[A]=> A => Int?
我也觉得强制的概念有点奇怪。对我来说,这就像创建一个返回函数的无括号方法。现在顶部的泛型我无法通过说文字函数执行方法定义的类型的闭包来解释其他。
总的来说,如果有人可以向我澄清正在发生的事情以及如何阅读该类型 [A]=> A => Int,那真的会有所帮助。
在 Scala 2.13.1 之前,我相信符号差异是根据SLS 3.3.1 方法类型设计的
方法类型在内部表示为 (Ps) ...一种特殊情况是没有任何参数的方法类型。他们写在这里=> T。
因为方法returnfuncdefGen没有任何参数,所以它的类型用=> T符号表示
scala> def returnfuncdefGen[A] = (i: A) => i.toString.length
def returnfuncdefGen[A] => A => Int
Run Code Online (Sandbox Code Playgroud)
在哪里 T = A => Int
有关 Scala 2.13.2 by 11416 MethodType.toString 以 Scala 格式打印的更改,请参阅 Dmytro 的答案#7798
如果你这样做
object App {
def returnfuncdefGen[A] = (i: A) => i.toString.length
def returnfuncdefGen1[A]() = (i: A) => i.toString.length
def returnfuncdefGen2[A](i: A) = i.toString.length
}
def printSignature(name: String): Unit = {
import scala.reflect.runtime.universe._
val t = typeOf[App.type].decl(TermName(name)).typeSignature
println(s"t=$t, showRaw(t)=${showRaw(t)}")
}
printSignature("returnfuncdefGen")
printSignature("returnfuncdefGen1")
printSignature("returnfuncdefGen2")
Run Code Online (Sandbox Code Playgroud)
你会看到的
t=[A]=> A => Int, showRaw(t)=PolyType(List(TypeName("A")), NullaryMethodType(TypeRef(ThisType(scala), scala.Function1, List(TypeRef(NoPrefix, TypeName("A"), List()), TypeRef(ThisType(scala), scala.Int, List())))))
t=[A]()A => Int, showRaw(t)=PolyType(List(TypeName("A")), MethodType(List(), TypeRef(ThisType(scala), scala.Function1, List(TypeRef(NoPrefix, TypeName("A"), List()), TypeRef(ThisType(scala), scala.Int, List())))))
t=[A](i: A)Int, showRaw(t)=PolyType(List(TypeName("A")), MethodType(List(TermName("i")), TypeRef(ThisType(scala), scala.Int, List())))
Run Code Online (Sandbox Code Playgroud)
那是因为 forNullaryMethodType toString被定义为=>
override def safeToString: String = "=> "+ resultType
Run Code Online (Sandbox Code Playgroud)
也许您希望将其定义为""但直到 2.13.1(包括)才如此。
在 2.13.2 forNullaryMethodType toString改为""
override def safeToString: String = resultType.toString
Run Code Online (Sandbox Code Playgroud)
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/Types.scala#L2953
所以现在在 2.13.2, 2.13.3 上面的代码打印
t=[A]A => Int, showRaw(t)=PolyType(List(TypeName("A")), NullaryMethodType(TypeRef(ThisType(scala), scala.Function1, List(TypeRef(NoPrefix, TypeName("A"), List()), TypeRef(ThisType(scala), scala.Int, List())))))
t=[A](): A => Int, showRaw(t)=PolyType(List(TypeName("A")), MethodType(List(), TypeRef(ThisType(scala), scala.Function1, List(TypeRef(NoPrefix, TypeName("A"), List()), TypeRef(ThisType(scala), scala.Int, List())))))
t=[A](i: A): Int, showRaw(t)=PolyType(List(TypeName("A")), MethodType(List(TermName("i")), TypeRef(ThisType(scala), scala.Int, List())))
Run Code Online (Sandbox Code Playgroud)
如你所愿。
顺便说一句,在 Dotty 0.26.0-bin-20200703-2dd1c93-NIGHTLY
def returnfuncdefGen[A] = (i: A) => i.toString.length
def returnfuncdefGen1[A]() = (i: A) => i.toString.length
def returnfuncdefGen2[A](i: A) = i.toString.length
def returnfuncdefGen3 = [A] => (i: A) => i.toString.length
def returnfuncdefGen4() = [A] => (i: A) => i.toString.length
>....def returnfuncdefGen[A] => A => Int
>....def returnfuncdefGen1[A](): A => Int
>....def returnfuncdefGen2[A](i: A): Int
>....def returnfuncdefGen3: PolyFunction{apply: [A](i: A): Int}
>....def returnfuncdefGen4(): PolyFunction{apply: [A](i: A): Int}
Run Code Online (Sandbox Code Playgroud)