函数编程中的“部分功能”到底是什么意思?


55

根据我的理解,部分函数是通过向函数传递比预期少的参数而获得的函数。例如,如果这在Python中直接有效:

>>> def add(x,y):
...    return x+y
... 
>>> new_function = add(1)
>>> new_function(2)
3

在上面的代码段中,new_function是部分功能。但是,根据Haskell Wiki,部分函数的定义为

局部函数是未针对指定类型的所有可能参数定义的函数。

因此,我的问题是:“部分函数”到底是什么意思?


37
您正在将部分应用的功能与部分功能混淆。
Willem Van Onsem,

11
Python partial执行部分应用程序,而Haskell自动执行。Wiki条目是指部分功能,这是数学术语。
L3viathan

9
严格来说,Haskell不执行部分功能应用程序。每个函数都带有一个参数,函数应用程序将一个函数应用于单个参数。柯里会模拟你会想到在通过首先模拟多个参数的函数另一种语言的部分应用程序。类似的东西add 3 5不是单一功能的应用程序。首先将其应用于add3以获取新功能,然后将其应用于
5。– chepner

在C#中,partial方法是项目代码库中其他位置可选实现的私有方法的前向声明。

1
您的示例可以成立:new_function = functools.partial(add, 1)
wjandrea

Answers:


76

您在这里混淆了两个概念。甲部分施加函数 [Haskell的维基]具有部分功能 [Haskell的维基]

部分应用的功能是:

Haskell中的部分应用程序涉及将少于完整数量的参数传递给带有多个参数的函数。

而部分函数确实是一个非全部函数:

局部函数是未针对指定类型的所有可能参数定义的函数。


24
这是一个很好的答案,但可以通过在答案本身中添加部分函数的示例来改进它。

2
我不确定我是否同意部分应用函数的确切定义。Haskell中的函数始终仅接受一个参数,而不接受“多个参数”。我将使用定义“ Haskell中的部分应用程序(部分应用程序函数)所提供的参数少于获取无法进一步应用于另一个参数的值所需的全部参数”。(从此处改编)
TerryA,

21

维基说的就是部分函数(在函数式编程和数学上下文中):函数未针对其所有可能的参数进行定义。在编程的上下文中,我们通常将“未定义”解释为以下几种情况之一,包括未定义的行为,异常或不终止。

部分函数的一个示例是整数除法,如果除数为0(在Haskell中它将抛出错误),则该整数函数未定义。

在上面的代码段中,new_function是局部函数。

该代码只会在Python中引起错误,但如果按预期工作,它将是一个完整的功能(不是部分功能)。

正如评论员已经指出的那样,您很可能会想到它是部分应用的功能这一事实。


18

答案说明全部,我将只用每种语言添加一个示例:

def add(x,y):
    return x+y

f = add(1)
print(f(3))

    f = add(1)
TypeError: add() missing 1 required positional argument: 'y'

既不是部分函数也不是咖喱函数,这只是一个您没有给出所有参数的函数

python中的咖喱函数应该是这样的:

partialAdd= lambda x: lambda y: x + y

plusOne = partialAdd(1)
print(plusOne(3))

4

在haskell中:

plus :: Int -> Int -> Int
plus x y = x + y

plusOne = plus 1

plusOne 4

5

python中的部分函数:

def first(ls):
    return ls[0]

print(first([2,4,5]))
print(first([]))

输出

2

print(first([]))
  File "main.py", line 2, in first
    return ls[0]
IndexError: list index out of range

在Haskell中,如您的链接所示:

head [1,2,3]
3

head []
*** Exception: Prelude.head: empty list

那么什么是总功能?

好吧,基本上是相反的:这是一个适用于该类型任何输入的函数。这是python中的示例:

def addElem(xs, x):
  xs.append(x)
  return xs

如果您使用一些技巧,这甚至适用于无限列表:

def infiniList():
    count = 0
    ls = []
    while True:
        yield ls
        count += 1
        ls.append(count)

ls = infiniList()
for i in range(5):
  rs = next(ls)

print(rs, addElem(rs,6))

[1, 2, 3, 4]
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]

相当于Haskell:

addElem :: a -> [a] -> [a]
addElem x xs = x : xs

addElem 3 (take 10 [1..])
=> [3,1,2,3,4,5,6,7,8,9,10]

在这里,这些功能不会永远挂起。概念是相同的:对于每个列表,功能都会起作用。


值得一提的是python 在标准库中支持部分功能
恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.