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, según el 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"?

55
Saurabh kukade 11 oct. 2019 a las 13:12

3 respuestas

La mejor respuesta

Estás confundiendo dos conceptos aquí. Una parcialmente aplicada función [haskell-wiki] con una función parcial [haskell-wiki].

Una función parcialmente aplicada es:

La aplicación parcial en Haskell implica pasar menos que el número completo 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.

75
Willem Van Onsem 11 oct. 2019 a las 10:15

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'

Esto no es ni una función parcial ni una función con currículum , esta 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 la 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á.

18
statox 14 oct. 2019 a las 08:25

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 .

20
sepp2k 11 oct. 2019 a las 10:19
58339040