python - ¿Qué se entiende exactamente por "función parcial" en la programación funcional?
haskell functional-programming (3)
Estás aquí confundiendo dos conceptos. Una función parcialmente aplicada [haskell-wiki] con una función parcial [haskell-wiki] .
Una función parcialmente aplicada es:
La aplicación parcial en Haskell implica pasar menos del número total de argumentos a una función que toma múltiples argumentos.
mientras que una función parcial es una función no total:
Una función parcial es una función que no está definida para todos los argumentos posibles del tipo especificado.
Según tengo entendido, las funciones parciales son funciones que obtenemos al pasar menos parámetros a una función de lo esperado. Por ejemplo, si esto fuera directamente válido en Python:
>>> def add(x,y):
... return x+y
...
>>> new_function = add(1)
>>> new_function(2)
3
En el fragmento anterior,
new_function
es una función parcial.
Sin embargo, de acuerdo con
Haskell Wiki
, la definición de función parcial es
Una función parcial es una función que no está definida para todos los argumentos posibles del tipo especificado.
Entonces, mi pregunta es: ¿qué se entiende exactamente por "función parcial"?
Las respuestas explican todo, solo agregaré un ejemplo en cada idioma:
def add(x,y):
return x+y
f = add(1)
print(f(3))
f = add(1)
TypeError: add() missing 1 required positional argument: ''y''
Esta no es una función parcial ni una función currificada , es solo una función que no dio todos sus argumentos .
Una función curry en python debería ser así:
partialAdd= lambda x: lambda y: x + y
plusOne = partialAdd(1)
print(plusOne(3))
4
y en haskell:
plus :: Int -> Int -> Int
plus x y = x + y
plusOne = plus 1
plusOne 4
5
Una función parcial en python:
def first(ls):
return ls[0]
print(first([2,4,5]))
print(first([]))
salida
2
print(first([]))
File "main.py", line 2, in first
return ls[0]
IndexError: list index out of range
Y en Haskell, como apareció su enlace :
head [1,2,3]
3
head []
*** Exception: Prelude.head: empty list
Entonces, ¿qué es una función total?
Bueno, básicamente lo contrario: esta es una función que funcionará para cualquier entrada de ese tipo. Aquí hay un ejemplo en python:
def addElem(xs, x):
xs.append(x)
return xs
y esto funciona incluso para listas infinitas, si usas un pequeño truco:
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]
Y el equivalente en 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]
Aquí las funciones no se cuelgan para siempre. El concepto es el mismo: para cada lista la función funcionará.
Una función parcial (tanto en el contexto de la programación funcional como de las matemáticas) es exactamente lo que dice el wiki: una función no definida para todos sus posibles argumentos. En el contexto de la programación, generalmente interpretamos "no definido" como una de varias cosas, incluido el comportamiento indefinido, las excepciones o la no terminación.
Un ejemplo de una función parcial sería la división de enteros, que no se define si el divisor es 0 (en Haskell arrojará un error).
en el fragmento anterior new_function es una función parcial.
Ese código simplemente causaría un error en Python, pero si funcionara como lo esperaba, sería una función total (es decir, no parcial).
Como los comentadores ya señalaron, lo más probable es que pienses en el hecho de que sería una función parcialmente aplicada .