【发布时间】:2019-11-27 06:56:36
【问题描述】:
背景
我试图回答一个问题“什么是函数?”并想知道我是否真的知道它是什么。请帮助理解 Scala 中的“函数”是什么。这可能听起来毫无意义的辩论,但请耐心等待。
问题
1。什么是函数
“函数”是要“应用于”单个“参数”以生成“值”的“计算/操作”。如果有多个参数,则可以将其转换为 ()()()... 称为柯里化。
- w 是一个名字
- b 是函数对象与名称的绑定
- c 是计算
- a 是应用程序
- g 是应用计算的参数
val w = ( ) => { }
^ ^ ^ ^ ^
| | | | |
(n) (b) (g) (a) (c)
这样说可以吗?
如果这是对参数应用计算:
() => { }
那么它实际上应该是相反的方向?
() <= { }
or
{ } => ()
2。定义分解
这是对什么是“def f (x:Unit):Unit = {}”的正确理解吗?
//--------------------------------------------------------------------------------
// The function literal says:
// 1. Define a "function" (ignore "method" here).
// 2. Bind the function to a name f.
// 3. It is to be applied to an "argument" of type Unit.
// 4. Bind the argument to a name x.
// 5. E-valuation, or appliation of the function to an argument generates an "value" of type Unit.
// 6. After evaluation, substitute it with the "value".
//--------------------------------------------------------------------------------
def f (x:Unit):Unit = {}
3。评估/申请
“评估”与“将函数应用于参数并产生值”相同吗?当我阅读lambda calculas时,使用了“应用”一词,但我认为也使用了“评估”。
单位
//--------------------------------------------------------------------------------
// The literal says:
// 1. Apply the function f
// 2. on the "argument" enclosed between '(' and ')', which is Unit.
// 3. and yield Unit as the "value" evaluated.
//--------------------------------------------------------------------------------
def f (x:Unit):Unit = {}
f()
和这个一样吗?如果是,“Unit”是一个对象吗?
f(Unit) // No error in Scala worksheet
是什么导致 Unit as 下面的参数出现“参数过多”错误?
// Define a function that applies on an argument x of type Unit to generate Unit
() => {} // res0: () => Unit = <function0>
(() => {}) // res1: () => Unit = <function0>
// Application
(() => {})()
/* Error: Too many arguments */
(() => {})(Unit)
4。参照透明
请告知是否正确。
以“def g(x:String): Unit = println(x)”为例,“参照透明”意味着g(x)总是可以用它的结果代替,不会破坏任何东西。
如果
g("foo")
总是可以替换为
Unit
那么它是引用透明的。但是,这里的 g 不是这种情况。因此 g 不是引用透明函数,因此它不是“纯”函数。随机也不是纯粹的。
{ scala.util.Random.nextInt } // res0: Int = -487407277
在 Scala 中,函数可以是纯函数或副作用函数。仅仅看一个函数是无法判断的。或者有没有办法标记,或者验证它是否是纯的?
5。方法不是函数
方法不能是要传递的第一类对象,但可以通过将其转换为函数来传递。
def g (x:String): Unit = println(x)
g("foo")
val _g = g _
_g("foo")
为什么方法不能是第一类对象?如果一个方法是一个对象,会发生什么或会破坏什么?
Scala 编译器做了巧妙的推理或补全,那么如果可以用 _ 将其转换为对象,为什么 Scala 不将其作为第一类对象呢?
6。 { ... } 是什么?
更新:
"=> T" 是按名称传递表达式调用以在函数内部进行评估,因此与 "{...}" 没有任何关系。 {...} 是一个块表达式。因此,以下所有内容均无效。
看起来“{...}”和“=> T”是一样的。
定义填充[T](n: Int)(elem: => T)
Array.fill[Int](3)({ scala.util.Random.nextInt })
{...} 本身产生一个值而不带任何参数。
{ scala.util.Random.nextInt } // res0: Int = 951666328
{ 1 } // res1: Int = 1
这是否意味着“应用程序”是一个独立的第一类对象,或者Scala编译器足够聪明,可以理解它是以下的缩写:
() => { scala.util.Random.nextInt }
or
val next = (x:Int) => { scala.util.Random.nextInt(x) }
如果是这样,“=> T”实际上是“() => T”吗?
【问题讨论】:
-
Scala 不是唯一具有函数的语言,函数的概念也不是源自 scala 等编程语言。如果您想了解什么是函数,请不要在编程语言的上下文中进行,因为这会导致您开始将语言语法与函数的真正含义混淆。函数处理输入和输出,并具有域(可接受的输入)和范围(可能的输出)的概念。 scala 添加的所有花哨语法只是为了便于阅读
-
一个方法不能是第一类成员,因为“它的定义”。在 OOP 中,
objects可以有value members和behaviour members。Methods应该是定义特定行为的对象的这些行为成员,它们本身不能是值。 -
这个问题太多了,不是关于需要解决的具体问题。请参阅how to ask a question 上的指南。
-
但一个简单的定义是:
f(x: A): B = y表示 A (我们称之为x)类型的对象之间的映射 B 类型的对象。该函数只是一个表达式(在这种情况下称为y),它可能使用x的值。