Outer product

Adds operations for outer product.

* `-flatten-n` is like flatten but only "flattens" `n` times.
* `-table` computes the "multiplication table" of the function. That means, call it on all combinations taken from the input lists.
* `-table-flat` is like Haskell's `fn <$> [1,2] <*> [3,4] <*> ...`. This is useful for "zipping" lists non-deterministically (unlike `-zip`, it takes all the possible pairs) and other similar operations.

These two operations are related via `(-table-flat fn lists) == (-flatten-n (1- (length lists)) (-table fn lists))`