Foldable and Foldable1 additions relating to minimum and maximum plus tests

This PR includes functionality around `Foldable` and `Foldable1` as follows:

Functions to return the min/max **of** a function applied to a foldable
```scala
Foldable[F].maximumOf[A, B: Order](fa: F[A])(f: A => B): Option[B]
Foldable[F].minimumOf[A, B: Order](fa: F[A])(f: A => B): Option[B]
```
Example with syntax:

```scala
val theMaxDelta = trades maximumOf (_.delta)
```

Functions to return the min/max **by** a function applied to a foldable
```scala
Foldable[F].maximumBy[A, B: Order](fa: F[A])(f: A => B): Option[A]
Foldable[F].minimumBy[A, B: Order](fa: F[A])(f: A => B): Option[A]
```
Example with syntax:

```scala
val tradeWithTheMaxDelta = trades maximumBy (_.delta)
```

There are also equivalents for `Foldable1` where the return type is not `Option` and I have created tests for `Foldable` and `Foldable1` also