public function reduce(callable $fn, $initial = 0)
    {
        if (!is_int($initial) and !is_float($initial)) {
            throw new InvalidArgumentException('Initial value must'
                . ' be an integer or float, ' . gettype($initial)
                . ' found.');
        }

        $carry = $initial;

        foreach ($this->a as $row) {
            foreach ($row as $value) {
                $carry = $fn($value, $carry);
            }
        }

        return $carry;
    }