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

时间:2019-10-11 10:12:26

标签: python haskell functional-programming partial-application partial-functions

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

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

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

  

部分函数是未为指定类型的所有可能参数定义的函数。

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

3 个答案:

答案 0 :(得分:74)

您在这里混淆了两个概念。一个partially applied function [haskell-wiki]和一个partial function [haskell-wiki]

部分已应用的功能是:

  

Haskell中的部分应用程序涉及将少于全部参数的数量传递给需要多个参数的函数。

部分函数确实是一个非总计函数:

  

部分函数是未为指定类型的所有可能参数定义的函数。

答案 1 :(得分:20)

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

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

  

以上代码段中的new_function是局部函数。

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

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

答案 2 :(得分:17)

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

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中,您的link出现了:

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]

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