## Map, fold, and filter
Use `List.map`, `List.fold_left`, `List.fold_right`, or `List.filter` to perform the following
operations.
* Return the product of a list of floats.
* Find the maximum of a list of floats.
* Add `1.0` to every element of a list of floats.
* Find those elements of a list of floats that are greater than `0.0`.
## Recursion, folding, and library functions
Write each of the following functions in each of three ways:
* as a recursive function, without using the `List` module,
* using `List.fold_left` or `List.fold_right`, but not other `List` module functions nor the
`rec` keyword, and
* using any combination of `List` module functions other than `fold_left` or `fold_right`,
but not the `rec` keyword.
You will therefore write a total of six functions.
1. Write a function `lst_and: bool list -> bool`, such that `lst_and [a1; ...; an]` returns
whether all elements of the list are `true`. That is, it returns `a1 && a2 && ... && an`. The
`lst_and` of an empty list is `true`.
2. Write a function `exists: ('a -> bool) -> 'a list -> bool`, such that
`exists p [a1; ...; an]` returns whether at least one element of the list satisfies the predicate
`p`. That is, it returns `(p a1) || (p a2) || ... || (p an)`. The `exists` of an empty
list is `false`.
## Matrices
A matrix can be represented with lists. In *row-major* representation, this matrix
$$ \left[ \begin{array}{c} 1 & 1 & 1 \\\\ 9 & 8 & 7 \end{array} \right] $$
would be represented as the list `[ [1; 1; 1]; [9; 8; 7] ]`.
Write the following functions. You might find it useful to define helper functions
and to investigate the several versions of the
`map` and `fold` functions in the `List` library.
* Implement a function `is_square: int list list -> bool` that returns whether the input matrix is
square. A matrix is *square* if the number of rows is equal to the number of columns.
* Implement a function `add_matrices: int list list -> int list list -> int list list`
for entry-wise matrix
addition. If the two input matrices are not the same size, the behavior is unspecified.
* Implement a function `multiply_matrices: int list list -> int list list -> int list list`
that returns the matrix product of the two input matrices. If the two input matrices are
not of sizes that can be multiplied together, the behavior is unspecified.