Future improvements

Improves the `Future` specs, removes some unnecessary uses of `.tap` and adds a few new features to `Future`:

* `Future#then` is like a mix between `Future#map` and `Future#flat_map`. The primary use case is when you don't know until you see the value if you want to synchronously transform the value or make another asynchronous operation.
* `Future.traverse` is a composition of `Array#map` and `Future.all`, which are very often occur together.
* `Future.reduce` is in its basic incarnation like a streaming version of `Future.all` followed by a `Future#map` with a `Array#reduce` inside.
* `Future#on_complete` now yields the value and error (either/or) in addition to the future.

Composition of futures has also been rewritten to only require the futures returned by the block given to `#flat_map` and `#fallback`, and the futures passed to `.all`, `.first`, `.traverse` and `.reduce` to implement `#on_complete`.

`Future.all` and `.first` have been changed to accept a list as first parameter, as well as varargs, so if you have a list of futures you don't need to splat. E.g. `Future.all([f1, f2, f3])` is now equivalent to `Future.all(f1, f2, f3)` – before, the former caused a `TypeError` or `NameError`.

```ruby
f = asynchronously_load_something
f = f.then do |result|
  if result.empty?
    asynchronously_load_some_fallback_value
  else
    result
  end
end
```

```ruby
ids = [1, 2, 3]
f = Future.traverse(ids) do |id|
  asynchronously_load_something(id)
end
f.value # => a list of the results of the loads
```

```ruby
f1 = asynchronously_load_list
f2 = asynchronously_load_list
f3 = asynchronously_load_list
future = Future.reduce([f1, f2, f3], []) do |accumulator, result|
  accumulator + result
end
future.value # => a (flat) concatenation of the loaded lists
```