Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将参数化方法强制转换为函数时,Scala的类型是否奇怪?_Scala_Methods - Fatal编程技术网

将参数化方法强制转换为函数时,Scala的类型是否奇怪?

将参数化方法强制转换为函数时,Scala的类型是否奇怪?,scala,methods,Scala,Methods,无法读取REPL返回的以下类型 def returnfuncdefGen[A] = (i: A) => i.toString.length returnfuncdefGen: [A]=> A => Int 虽然我确实理解这一点 def returnfuncdefGen[A](i: A) = i.toString.length returnfuncdefGen: [A](i: A)Int 第一个版本是FP simplified(scala)的作者所说的将参数化方法强制

无法读取REPL返回的以下类型

def  returnfuncdefGen[A] = (i: A) => i.toString.length

returnfuncdefGen: [A]=> A => Int
虽然我确实理解这一点

def  returnfuncdefGen[A](i: A) = i.toString.length

returnfuncdefGen: [A](i: A)Int
第一个版本是FP simplified(scala)的作者所说的将参数化方法强制为函数

一个人如何准确地理解这个[A]=>A=>Int

我也觉得强迫的概念有点奇怪。我觉得这就像创建了一个返回函数的无父方法。现在,泛型在顶部,我不能通过说literal函数执行该方法定义的类型的闭包来解释其他


总的来说,如果有人能向我澄清发生了什么,以及如何读取该类型A=>Int
[A]=>A=>Int
是一个类型参数为
A
且没有返回函数`A=>Int的参数的函数


这不同于
def returnfuncdefGen[A](i:A)=i.toString.length
,它是一个类型参数为
A
的函数,并且是一个类型为
A
的单参数,它在Scala 2.13.1之前返回一个
Int

,我相信符号上的差异是根据设计的

如果您这样做,则方法类型在内部表示为(Ps)

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")
你会看到的

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())))
这是因为for
NullaryMethodType
toString
被定义为
=>

override def safeToString: String = "=> "+ resultType
也许您希望将其定义为
,但直到2.13.1(包括)才是这样

在2.13.2中,对于
NullaryMethodType
toString
已更改为
“”

现在在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())))
如你所愿

顺便说一句,在Dotty 0.26.0-bin-20200703-2dd1c93-每晚

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}

写第一段就意味着有强迫行为发生?Def是否强制成为函数?否则,为什么它不是一个没有参数返回函数的类型a的方法呢?这很奇怪,因为
def returnfuncdef=(i:Int)=>i+2
不强制执行任何操作?是吗?这里的类型是Int=>Int。对我来说,它是一个无父类的方法,并返回一个函数。“
[a]=>a=>Int
是一个函数…”,“
def returnfuncdefGen[a](i:a)=i.toString.length
这是一个函数…”更准确地说,不是一个函数,而是一个方法。函数也不是函数,两者都是方法。但是第一个方法返回一个函数。函数和方法之间的差异非常重要,特别是对于新手。有关差异的详细解释,请参见。@LuisMiguelMejíaSuárez完全同意,唯一的问题是符号。通常,方法的返回类型不使用arrow。但在这种情况下确实如此。返回的函数是
A=>Int
,但是你有
[A]=>A=>Int
,换句话说,`[A]=>``是关于方法的,这就是我的问题所在。我同意,我只是觉得符号不对,我不认为这是强迫。它只是一个返回函数的方法,我想问题是指这个页面(“将参数化方法强制转换为函数”)我想在Scala语言规范中没有“强制”的概念(尽管在Haskell中有强制)。将
def returnfuncdefGen[A](i:A)=i.toString.length
转换为
def returnfuncdefGen[A]=(i:A)=>i.toString.length
类似于η-减脂箭头是右关联的(我认为),因此您可以想象A=>Int周围的paren,在第一个方法中添加一个空参数列表可能会对您有所帮助。我想我明白您的意思了。你希望它是[A](A)=>Int?酷。2.13.2中更改了来源,但规范没有更改。请参阅我答案中的详细信息。@DmytroMitin Dotty似乎仍然以旧方式打印它。
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}