## Expressions and types Give OCaml expressions that have the following types. * int list * string -> string list * string list -> string ## Patterns Using pattern matching, write three functions, one for each of the following properties. Your functions should return true if the input list has the property and false otherwise. * the list's first element is "cs3110" * the list has exactly two or four elements; do not use the length function * the first two elements of the list are equal ## Functions on lists * Write a function that returns the product of all the elements in a list. (The product of all the elements of an empty list is 1.) * Write a function that concatenates all the strings in a list. (The concatenation of all the strings in an empty list is the empty string "".) ## Library functions Consult the [List standard library](http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html) to easily implement the following functions: * Write a function that returns the last element of a list. *Hint:* this can be solved by combining two library functions, and without writing any pattern matching code of your own. If the list is empty, your function may throw an exception. * Write a function any_zeroes : int list -> bool that returns true if and only if the input list contains at least one 0. *Hint:* this can be solved by using one library function, and without writing any pattern matching code of your own. Your solutions should need only about one line of code. ## Tail recursion * Write a function take : int -> 'a list -> 'a list such that take n lst returns the first n elements of lst. If lst has fewer than n elements, return all of them. * Write a function drop : int -> 'a list -> 'a list such that drop n lst returns all but the first n elements of lst. If lst has fewer than n elements, return the empty list. Your functions must be tail recursive. Test them on long lists with large values of n to see whether they run out of stack space. Here is code to produce a long list:  let (--) i j = let rec from i j l = if i>j then l else from i (j-1) (j::l) in from i j [] let longlist = 0 -- 1_000_000  Note that code itself is tail recursive. ## More functions on lists * Write a function is_unimodal : int list -> bool that takes an integer list and returns whether that list is unimodal. A *unimodal list* is a list that monotonically increases to some maximum value then monotonically decreases after that value. Either or both segments (increasing or decreasing) may be empty. A constant list is unimodal, as is the empty list. * Write a function powerset : int list -> int list list that takes a set *S* represented as a list and returns the set of all subsets of *S*. The order of subsets in the powerset and the order of elements in the subsets do not matter. *Hint:* Consider the recursive structure of this problem. Suppose you already have p, such that p = powerset s. How could you use p to compute powerset (x::s)?