Recursive Definitions

In the definition of a function , we can use the function itself:

fact :: Integer -> Integer
fact n
    | n > 0   = n * (fact (n - 1))
    | n == 0  = 1
    | n < 0   = error "negative argument"

Definitions by pattern matching

Functions may also be defined using pattern matching on their arguments.

fact :: Integer -> Integer
fact 0 = 1
fact n = n * (fact (n - 1))

More language features

  • !! is the indexing operator, it returns the n-th element of a list [3,5,2,1] !! 0 = 3
  • : is the cons operator for lists, it takes an element and a list and returns a list where the element has been added to the front, i.e. 3:1:2:[]
  • zipWith f l1 l2 takes a function f and applies it to the elements at the same position in lists l1 and l2, returning a new list with the result. zipWith (+) [1,3,4] [3,2,5] == [4,5,9]
  • tail xs returns the tail of the list xs

Local Definitions

We can write:

-- [..] where [variable] = [value] syntax
f x = a + 1 where a = x / 2
 
-- let [variable] = [value] in [..] syntax
f x = let a = x / 2 in a + 1
 
-- we can write several location definitions
f x = square (succ x)
  where square z = z * z;
	    succ   x = x + 1

To evaluate the where syntax: e[a] where a = e'

  1. Evaluate obtaining result
  2. Replace by in
  3. Evaluate

Arithmetic functions

Arithmetic operators are also functions (primitives) used in infix notation, 3 + 4. We can also use them in prefix notation if we enclose them in brackets: (+) 3 4.

(+) denotes the curryfied version of .

 +  :: (Integer, Integer) -> Integer
(+) :: Integer -> Integer -> Integer

Standard functions use prefix syntax by default, but may be made infix by quoting them like so: 10 'div' 2.

Some notes:

  • are left associative.
  • should be read as .
  • (+) 1 is the successor function.
  • (*) 2 is the function that double its argument

Functional composition

Functions are the building blocks of functional languages. One way of combining functions is by composition, written infix as . Composition is itself a (pre-defined) function.

(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

We can only compose functions whose types match.