Functional Programming – What Are ‘Total’ and ‘Partial’ Functions?

functional programming

I'm not finding via Google any explanation that my brain can grasp. Can someone explain this, and if possible, give an example of each using either pseudocode or C#?

The term 'total' function was introduced to me in the comments section of this question. The comment is:

when you work with total functions, you can compose them with other functions and use them in higher order functions without worrying about error results "not encoded in the type", i.e. exceptions. – Andres F.

I'm intrigued by this comment.

Best Answer

Here's a reasonable definition from the Haskell wiki:

A total function is a function that is defined for all possible values of its input. That is, it terminates and returns a value.

A partial function is a function that is not defined for all possible input values; in some cases instead of returning a value, it may never return at all (think infinite cycles), throw an exception (which usually states "this is undefined for this input value" or "unexpected input" or whatever) or simply crash the system.

A well-known example of a partial function is the integer division, a divided by b: it's not defined when b is zero!

Another example is head, the Haskell function that takes the first element of a list, which throws an error if the list is empty! Something like this:

head :: [a] -> a  // this is the signature
head (first : rest) = first
head _ = ... // This is an error! What is the first element of the empty list?

Partial functions like head unfortunately exist in Haskell for historical reasons. Note it can be made total like this:

headMaybe :: [a] -> Maybe a
headMaybe (first : rest) = Just first
headMaybe _ = Nothing

Then you can safely call head [] ([] is the empty list) and it will return Nothing instead of throwing.

Note that when looking at the original head, I cannot know just by looking at its definition that it may throw an error in some cases; I need to look at its implementation instead! That's bad. Compare this with headOption: just by looking at its type I know it sometimes returns a Just x and sometimes a Nothing, and I don't have to examine the implementation.