Source

John Whitington, OCaml from the Very Beginning, Chapter 2: Names and Functions

Contents

Question 1

Write a function which multiplies a given number by ten. What is its type?

The type is int because we’re using the int multiplication operator *. The equivalent for a float would be let tenx x = 10.0 *. x.

1
2
let tenx x = 10 * x
let _ = assert (100 = tenx 10);;

Question 2

Write a function which returns true if both of its arguments are non-zero, and false otherwise. What is the type of your function?

Type is bool.

1
2
3
4
5
6
7
8
9
10
11
let nonzero a b = a <> 0 && b <> 0

let _ = 
    assert (nonzero 1     1);
    assert (nonzero 1   ~-1); (* special integer negation syntax *)
    assert (nonzero ~-1   1);
    assert (nonzero ~-1 ~-1);
    assert (not (nonzero 0     1));
    assert (not (nonzero 1     0));
    assert (not (nonzero 0   ~-1));
    assert (not (nonzero ~-1   0));;

Question 3

Write a recursive function which, given a number n, calculates the sum 1 + 2 + 3 + … + n. What is its type?

Type is int.

1
2
3
4
5
6
7
8
let rec f n = if n < 1 then 0 else n + (f (n - 1))

let _ = 
    assert (0 = f ~-1);
    assert (0 = f 0);
    assert (1 = f 1);
    assert (3 = f 2);
    assert (6 = f 3);;

Question 4

Write a function power x n which raises x to the power n. Give its type.

Type is int. Does not handle values less than 1 for either x or n.

1
2
3
4
5
6
7
8
9
10
11
let rec power x n = if n < 2 then x else x * (power x (n - 1))

let _ =
    assert (power 1 1 = 1);
    assert (power 1 2 = 1);
    assert (power 1 3 = 1);
    assert (power 2 1 = 2);
    assert (power 2 2 = 4);
    assert (power 2 3 = 8);
    assert (power 3 2 = 9);
    ;;

Question 5

Write a function isconsonant which, given a lower-case character in the range 'a''z', determines if it is a consonant.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let isvowel c =
    if c = 'a' || c = 'e' || c = 'i' || c = 'o' || c = 'u'
    then true else false

let isconsonant c = not (isvowel c)

let _ =
    assert (not (isconsonant 'a'));
    assert (not (isconsonant 'e'));
    assert (not (isconsonant 'i'));
    assert (not (isconsonant 'o'));
    assert (not (isconsonant 'u'));
    assert (isconsonant 'b');
    assert (isconsonant 'q');
    assert (isconsonant 'z');
    ;;

Question 6

What is the result of the expression let x = 1 in let x = 2 in x + x?

The result is a warning that x is an unused variable. The expression let x = 2 in x + x evaluates to 4, leaving no referent for the variable x in the first part of the expression.

Question 7

Can you suggest a way of preventing the non-termination of the factorial function in the case of a zero or negative argument?

A pragmatic solution is to return 1 for a <= 0.

1
2
3
4
5
6
7
8
9
let rec factorial a =
    if a <= 1 then 1 else a * factorial (a - 1)

let _ =
    assert (24 = factorial 4);
    assert (1 = factorial 1);
    assert (1 = factorial 0);
    assert (1 = factorial ~-1);
    ;;

Execute this file

$ codedown ocaml < 2022-12-17-naming.md | grep . | ocaml -stdin