Add an example of covariance and contravariance in function type parameters.

Even though the type of the function passed to Library.printBookList is
Book => AnyRef, the actual function passed to it in Customer, getTitle,
Publication => String, type checks.

If you think about it, this makes sense. The Liskov Substitution
Principle says that every subtype should be suitable as a drop-in
replacement for any of its supertypes. Every Book is also a Publication,
so a function that takes Publications type checks for a function that
takes Books.

Similarly, on the return side, printBookList expects a function that
returns AnyRef. String is an AnyRef, so that also type checks, because
every String is also an AnyRef.

This example of type covariance and contravariance also lines up with
how Java does generics as per the PECS acronym, Producer Extends,
Consumer Super.