20

有人可以用一些很好的例子清楚地解释它。在解释函数式编程时,我在 Scala 中遇到了这个声明。

4

6 回答 6

24

“一流”不是一个正式定义的概念,但它通常意味着一个实体具有三个属性:

  1. 它可以无限制地用于任何“普通”值可以使用的地方,即从函数传递和返回,放入容器等。

  2. 它可以不受限制地在任何“普通”值可以构造的地方构造,即在本地、在表达式中等等。

  3. 它可以以类似于“普通”值的方式进行类型化,即为这样的实体分配一个类型,并且可以与其他类型自由组合。

对于函数,(2) 尤其意味着局部函数可以使用范围内的所有名称,即您有词法闭包。它还经常带有用于构造的匿名形式(例如匿名函数),但这不是严格要求的(例如,如果语言具有足够通用的 let 表达式)。第 (3) 点在无类型语言中是微不足道的。

所以你明白为什么Scala(和函数式语言)中的函数被称为一等的。这里有一些其他的例子。

  • C/C++ 中的函数不是一流的。虽然 (1) 和 (3) 可以通过函数指针获得,但 (2) 不支持适当的函数。(这一点经常被忽视。)

  • 同样,数组和结构在 C 语言中也不是一流的。

  • Scala 中的类不是一流的。您可以定义和嵌套它们,但不能将它们传递给函数(仅它的实例)。有些面向对象语言具有一流的类,事实上,通知 Scala 设计的所谓 nuObj 演算也允许这样做。

  • 一流的模块是类 ML 语言中经常需要的功能。它们很困难,因为它们会导致无法确定的类型检查。一些 ML 方言允许将模块包装为一流的值,但可以说,这并不能使模块本身成为一流的。

于 2012-05-28T10:13:42.973 回答
15

这意味着函数可以像整数、序列等一样传递。

一个例子(虽然不是 Scala):

>>> def add2(x):
...   return x + 2
... 
>>> map(add2, [1, 2, 3])
[3, 4, 5]
于 2012-05-27T21:14:59.423 回答
8

任何编程语言都有一组基本的语言特性,您可以使用它们来操作值,以便编写程序。这些是诸如:“将值传递给函数”,“将变量绑定到值,然后像使用值一样使用变量”等。

每当您看到声称一种语言具有“X 作为一流值”或具有“一流 Xs”的声明时,这意味着该语言允许您在 Xs 上使用这些基本语言功能。另一种说法是该语言将 Xs 视为值。

因此,您可以填空表示某些语言支持使用某种特定类型的事物作为值。例如,Scala 有一流的函数(或者函数是 Scala 中的值):

def plusOne(x : Int) = x + 1
val func : Int => Int = plusOne
println(func(1))     // prints 2

Python 有一流的函数,但也有一流的(类是 Python 中的值):

class Foo(object):
    def __init__(self, thing):
        self.thing = thing

cls = Foo
instance = cls(5)
print instance.thing            # prints 5
print isinstance(thing, cls)    # prints True
print isinstance(thing, Foo)    # prints True

这可能看起来不多,但是任何编程语言的基本特征都说明了你可以用值做什么,这会导致更多的东西;如果您可以将函数用作值,那么(与任何其他值一样)您可以将它们放入容器中,通过调用其他代码来检索未知的,等等。

相比之下,Java 没有一流的功能。你不能把一个函数放在一个变量中,把一个函数传递给另一个函数,或者接收一个函数作为函数的返回值。函数不是 Java 中的值。Java 也没有一流的类。

于 2012-05-28T05:28:30.547 回答
3

这意味着函数是一个对象。就像任何其他对象一样,它可以分配给一个变量,或者传递给一个函数,或者对象可以做的任何其他事情。

例如,这里有一个变量f,它包含一个将整数加 1 的函数对象:

scala> val f = (n: Int) => n + 1
f: Int => Int = <function1>       // Has type Int => Int; Int input, Int output

它可以作为参数传递给mapa 的函数List[Int]

scala> List(1,2,3).map(f)         // map requires argument of type Int => Int
res0: List[Int] = List(2, 3, 4)
于 2012-05-27T21:15:08.097 回答
2

这个术语取自纯函数式语言,例如 Haskell 或 Erlang,其中函数是一等公民。这意味着函数可以作为参数传递给其他函数,并且函数可以返回其他函数。

因为函数是一等公民——我们有一个函数类型——用箭头表示。在 haskel 中:(->)在 skala 中:(=>)

考虑地图功能。它是一个函数,它接受一个函数和一个列表作为其参数,并将给定的函数应用于列表的所有元素:

在哈斯克尔:

map(\x->x+1)[1,2,3] 
= [2,3,4]

在斯卡拉:

List(1,2,3) map (x => x + 1) 
= [2,3,4]

(\x->x+1)并且(x => x + 1) 是作为参数传递给 map 函数的函数(由 lambda 表达式表示)。

于 2012-05-28T16:27:31.123 回答
0

在函数式编程中,函数可以赋值给变量,作为参数传递给其他函数,并作为其他函数的值返回。这样的函数被称为First Class Functions。高阶函数是将函数作为参数或返回函数的函数。

例子:

var increase = (x: Int) => x + 1
于 2018-01-30T06:15:27.910 回答