What exactly is meant by "partial function" in functional programming?

PythonHaskellFunctional ProgrammingPartial ApplicationPartial Functions

Python Problem Overview


According to my understanding, partial functions are functions that we get by passing fewer parameters to a function than expected. For example, if this were directly valid in Python:

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

In the snippet above, new_function is a partial function. However, according to the Haskell Wiki, the definition of partial function is

> A partial function is a function that is not defined for all possible arguments of the specified type.

so, my question is: what exactly is meant by "partial function"?

Python Solutions


Solution 1 - Python

You are here confusing two concepts. A partially applied function [haskell-wiki] with a partial function [haskell-wiki].

A partially applied function is:

> Partial application in Haskell involves passing less than the full number of arguments to a function that takes multiple arguments.

whereas a partial function indeed is a non-total function:

> A partial function is a function that is not defined for all possible arguments of the specified type.

Solution 2 - Python

A partial function (both in the context of functional programming and mathematics) is exactly what the wiki says: a function not defined for all of its possible arguments. In the context of programming, we usually interpret "not defined" as one of several things, including undefined behaviour, exceptions or non-termination.

An example of a partial function would be integer division, which is not defined if the divisor is 0 (in Haskell it will throw an error).

> in above snippet new_function is partial function.

That code would simply cause an error in Python, but if it worked as you intended, it would be a total (meaning not partial) function.

As commentors already pointed out, you're most likely thinking of the fact that it'd be a partially applied function.

Solution 3 - Python

The answers explain all, I will just add one example in each language:

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

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

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

this is neither a partial function nor a curried function, this is only a function that you didn't gave all its arguments.

A curried function in python should be like this:

partialAdd= lambda x: lambda y: x + y

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

4

and in haskell:

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

plusOne = plus 1

plusOne 4

5

A partial function in 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

And in Haskell, as your link showed up:

head [1,2,3]
3

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

>So what is a total function?

Well, basically the opposite: this is a function that will work for any input of that type. Here is an example in python:

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

and this works even for infinite lists, if you use a little trick:

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]

And the equivalent in 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]

Here the functions doesn't hang forever. The concept is the same: for every list the function will work.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSaurabh kukadeView Question on Stackoverflow
Solution 1 - PythonWillem Van OnsemView Answer on Stackoverflow
Solution 2 - Pythonsepp2kView Answer on Stackoverflow
Solution 3 - PythonDamian LatteneroView Answer on Stackoverflow