Concepts of Programming Languages

(Sean Pound) #1
15.8 Haskell 709

Notice that the : operator is just like ML’s :: operator.^12 Using : and pattern
matching, we can define a simple function to compute the product of a given
list of numbers:

product [] = 1
product (a:x) = a * product x

Using product, we can write a factorial function in the simpler form

fact n = product [1..n]

Haskell includes a let construct that is similar to ML’s let and val. For
example, we could write

quadratic_root a b c =
let
minus_b_over_2a = − b / (2.0 * a)
root_part_over_2a =
sqrt(b ^ 2 − 4.0 * a * c) / (2.0 * a)
in
minus_b_over_2a − root_part_over_2a,
minus_b_over_2a + root_part_over_2a

Haskell’s list comprehensions were introduced in Chapter 6. For example,
consider the following:

[n * n * n | n <− [1..50]]

This defines a list of the cubes of the numbers from 1 to 50. It is read as “a list
of all n*n*n such that n is taken from the range of 1 to 50.” In this case, the
qualifier is in the form of a generator. It generates the numbers from 1 to 50.
In other cases, the qualifiers are in the form of Boolean expressions, in which
case they are called tests. This notation can be used to describe algorithms
for doing many things, such as finding permutations of lists and sorting lists.
For example, consider the following function, which when given a number n
returns a list of all its factors:

factors n = [ i | i <− [1..n `div` 2], n `mod` i == 0]

The list comprehension in factors creates a list of numbers, each temporarily
bound to the name i, ranging from 1 to n/2, such that n `mod` i is zero. This
is indeed a very exacting and short definition of the factors of a given number.
The backticks (backward apostrophes) surrounding div and mod are used to


  1. It is interesting that ML uses : for attaching a type name to a name and : : for CONS, while
    Haskell uses these two operators in exactly opposite ways.

Free download pdf