Exercises

Mutable fields and refs

Exercise: mutable fields [✭]

Define an OCaml record type to represent student names and GPAs. It should be possible to mutate the value of a student's GPA. Write an expression defining a student with name "Alice" and GPA 3.7. Then write an expression to mutate Alice's GPA to 4.0.

Exercise: refs [✭]

Give OCaml expressions that have the following types. Use utop to check your answers.

  • bool ref
  • int list ref
  • int ref list

Exercise: inc fun [✭]

Define a reference to a function as follows:

# let inc = ref (fun x -> x+1);;

Write code that uses inc to produce the value 3110.

Exercise: addition assignment [✭✭]

The C language and many languages derived from it, such as Java, has an addition assignment operator written a += b and meaning a = a + b. Implement such an operator in OCaml; its type should be int ref -> int -> unit. Here's some code to get you started:

let (+:=) x y = ...

And here's an example usage:

# let x = ref 0;;
# x +:= 3110;;
# !x
- : int = 3110

Exercise: physical equality [✭✭]

Define x, y, and z as follows:

let x = ref 0
let y = x
let z = ref 0

Predict the value of the following series of expressions:

# x == y;;
# x == z;;
# x = y;;
# x = z;;
# x := 1;
# x = y;;
# x = z;;

Check your answers in utop.

Arrays

For the next couple exercises, let's use the following type:

(* AF: the float array [| x1; ...; xn |] represents the 
 *     vector (x1, ..., xn) 
 * RI: the array is non-empty *)
type vector = float array
Exercise: norm [✭✭]

The Euclidean norm of an \(n\)-dimensional vector \(x = (x_1, \ldots, x_n)\) is written \(|x|\) and is defined to be

Write a function norm : vector -> float that computes the Euclidean norm of a vector. Your function should not mutate the input array. Hint: although your first instinct is likely to reach for a loop, instead try to use Array.map and Array.fold_left or Array.fold_right.

Every vector can be normalized by dividing each component by \(|x|\); this yields a vector with norm 1:

\[\left(\frac{x_1}{|x|}, \ldots, \frac{x_n}{|x|}\right)\]

Exercise: normalize [✭✭]

Write a function normalize : vector -> unit that normalizes a vector "in place" by mutating the input array. Here's a sample usage:

# let a = [|1.; 1.|];;
val a : float array = [|1.; 1.|]
# normalize a;;
- : unit = ()
# a;;
- : float array = [|0.7071...; 0.7071...|]

Hint: Array.iteri.

Exercise: normalize loop [✭✭]

Modify your implementation of normalize to use one of the looping expressions.

Exercise: norm loop [✭✭]

Modify your implementation of norm to use one of the looping expressions. Here is pseudocode for what you should do:

initialize norm to 0.0
loop through array
  add to norm the square of the current array component
return sqrt of norm

Exercise: init matrix [✭✭✭]

The array module contains two functions for creating an array: make and init. make creates an array and fills it with a default value, while init creates an array and uses a provided function to fill it in. The library also contains a function make_matrix for creating a two-dimensional array, but it does not contain an analogous init_matrix to create a matrix using a function for initialization. Write a function init_matrix : int -> int -> (int -> int -> 'a) -> 'a array array such that init_matrix n o f creates and returns an n by o matrix m with m.(i).(j) = f i j for all i and j in bounds. See the documentation for make_matrix for more information on the representation of matrices as arrays.

Challenge: Doubly-linked lists

Exercise: doubly linked list [✭✭✭✭]

Here is an OCaml file with types and functions for mutable doubly-linked lists. Complete the implementations in that file. Test your code.

Hint: draw pictures! Reasoning about mutable data structures is typically easier if you draw a picture.

results matching ""

    No results matching ""