Difference between revisions of "Partial functions"

From HaskellWiki
Jump to navigation Jump to search
(Partial functions are bad, mmmmmmkay)
 
Line 5: Line 5:
 
* <hask>div</hask>: undefined if the divisor is zero
 
* <hask>div</hask>: undefined if the divisor is zero
   
The opposite is a total function. You should *strive* to avoid partial functions and instead write total ones. This makes it much easier to reason about your code and makes "if your code compiles, it probably works" true for your code more often.
+
The opposite is a total function. You should <em>strive</em> to avoid partial functions and instead write total ones. This makes it much easier to reason about your code and makes "if your code compiles, it probably works" true for your code more often.
   
 
Usually if you have a partial function, it's because your types are incorrect and you should fix your types rather than writing partial functions which guarantee the impossible.
 
Usually if you have a partial function, it's because your types are incorrect and you should fix your types rather than writing partial functions which guarantee the impossible.
   
A good example of this is <hask>head</hask>. You shouldn't use this function or write functions like it. The problem is in the *type*, it says <hask>[a] -> a</hask> which is actually impossible as far as total functions are concerned. Why? Because you might have an empty list! Instead, a more honest type that lets you write a total function would be <hask>[a] -> Maybe a</hask>. This makes the possibility of not getting a result more explicit and keeps your functions total.
+
A good example of this is <hask>head</hask>. You shouldn't use this function or write functions like it. The problem is in the <em>type</em>, it says <hask>[a] -> a</hask> which is actually impossible as far as total functions are concerned. Why? Because you might have an empty list! Instead, a more honest type that lets you write a total function would be <hask>[a] -> Maybe a</hask>. This makes the possibility of not getting a result more explicit and keeps your functions total.
   
 
You almost never have an excuse for writing a partial function!
 
You almost never have an excuse for writing a partial function!

Latest revision as of 16:53, 15 November 2014

A partial function is a function that is not defined for all possible arguments of the specified type. Examples in the Haskell standard library are:

  • head, tail: undefined for empty lists
  • (!!): undefined if the index is at least as big as the list length
  • div: undefined if the divisor is zero

The opposite is a total function. You should strive to avoid partial functions and instead write total ones. This makes it much easier to reason about your code and makes "if your code compiles, it probably works" true for your code more often.

Usually if you have a partial function, it's because your types are incorrect and you should fix your types rather than writing partial functions which guarantee the impossible.

A good example of this is head. You shouldn't use this function or write functions like it. The problem is in the type, it says [a] -> a which is actually impossible as far as total functions are concerned. Why? Because you might have an empty list! Instead, a more honest type that lets you write a total function would be [a] -> Maybe a. This makes the possibility of not getting a result more explicit and keeps your functions total.

You almost never have an excuse for writing a partial function!

There are methods to avoid the use of partial functions.