Что именно подразумевается под «частичной функцией» в функциональном программировании? - PullRequest
54 голосов
/ 11 октября 2019

Насколько я понимаю, частичные функции - это функции, которые мы получаем, передавая в функцию меньше параметров, чем ожидалось. Например, если это было непосредственно допустимо в Python:

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

В приведенном выше фрагменте new_function является частичной функцией. Однако согласно Haskell Wiki определение частичной функции:

Частичная функция - это функция, которая не определена для всех возможных аргументов указанного типа.

Итак, мой вопрос: что именно означает «частичная функция»?

Ответы [ 3 ]

74 голосов
/ 11 октября 2019

Вы здесь путаете два понятия. A частично применяется функция [haskell-wiki] с частичной функцией [haskell-wiki] .

Частично примененная функция:

Частичное применение в Haskell включает в себя передачу меньше полного числа аргументов функции, которая принимаетнесколько аргументов.

, тогда как частичная функция действительно является неполной функцией:

Частичная функция - это функция, которая не определена для всех возможных аргументов указанноготип.

20 голосов
/ 11 октября 2019

Частичная функция (как в контексте функционального программирования, так и математики) - это именно то, что говорит вики: функция, не определенная для всех возможных аргументов. В контексте программирования мы обычно интерпретируем «не определено» как одну из нескольких вещей, включая неопределенное поведение, исключения или отсутствие завершения.

Примером частичной функции может быть целочисленное деление, которое не определеноесли делитель равен 0 (в Haskell он выдаст ошибку).

в приведенном выше фрагменте new_function является частичной функцией.

Этот код просто вызовет ошибку в Python, но если бы это работало так, как вы хотели, это была бы полная (то есть не частичная) функция.

Как уже отмечали комментаторы, вы, скорее всего, думаете о том, что это будет частично примененная функция.

16 голосов
/ 11 октября 2019

Ответы объясняют все, я просто добавлю один пример на каждом языке:

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([]))

output

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]

Здесь функции не зависают вечно. Концепция такая же: для каждого списка функция будет работать.

...