public function partition($expression)
    {
        $outer = new MapOfCollections;
        $proto = new static;

        $this->walk(function ($v, $k) use ($expression, $outer, $proto) {
            $partition = $this->call($expression, $v, $k);

            $inner = $outer->has($partition) ? $outer->get($partition) : clone $proto;
            $inner->set($k, $v);

            $outer->set($partition, $inner);
        });

        return $outer;
    }