【问题标题】:Understand the signature of partially applied function for function literal理解函数字面量的部分应用函数的签名
【发布时间】:2019-06-11 03:56:02
【问题描述】:

我无法理解函数文字的部分应用函数的签名。例如,考虑以下以相同方式工作的函数和方法定义:

def meth(x: Int): Unit = ()
val func = (x: Int) => ()

现在从上面的每个方法/函数中创建一个部分应用的函数。注意结果函数的签名:

val f = meth _  // Int => Unit
val g = func _  // () => Int => Unit

我不明白为什么func _ 的签名包含() => 部分,这使得g 必须被称为g()(1) 而不是g(1)

【问题讨论】:

  • 您可以将此视为错误。在 scala 2.13 中,您将收到错误消息 _ must follow method for val g = func _,因为用于将方法转换为函数文字的 eta 扩展只适用于方法。
  • @BogdanVakulenko 你有提到这个错误或建议的改变吗?
  • 我的错。不是错误。适用于 scala 2.13 以及顶级方法。 stackoverflow.com/questions/52525520/… - 你的问题的另一个答案。

标签: scala


【解决方案1】:

例如,考虑以下以相同方式工作的函数和方法定义:

方法和函数在 Scala 中相同。它们实际上非常不同。方法不是一流的对象,而函数是。也就是说,你永远不会有一个类型是方法类型的变量。

因此,让我们看看 没有下划线的类型。

val f = meth
val g = func

由于meth 是一个方法,它会被调用。所以第一行将尝试不带参数调用meth(),这是一个错误。但是func 是一个普通值,所以没有问题。我们将为func 设置另一个别名,称为g

val f = meth _
val g = func _

为了允许我们将方法视为对象,Scala 引入了_ 语法。当与方法一起使用时,它将该方法转换为函数对象。所以meth _ 是一种特殊的方法语法,它将它变成一个函数。另一方面,func _ 正在获取一个 (请记住,函数是对象,就像字符串或其他任何东西一样)并将其提升为函数对象。 “最简单”的方法是添加一个空参数列表,这正是 Scala 所做的。

tl;dr 在名称后面加上_ 会将事物变成函数对象。如果事物是​​一种方法,它就不会应用它。如果事物是​​一个值(包括但不限于一个函数),它会产生一个新的函数对象。

【讨论】:

  • "如果事物是​​一个值(包括但不限于一个函数),它会产生一个新的函数对象。总结的很不错。刚刚意识到我可以val x = 1; val f = x _; f() == 1
猜你喜欢
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多