Fix sparsity caching

We were turning a single Map as the maps argument into a pair of maps
prior to using it as a cache key. As a consequence, constructing
another sparsity with that same Map would not be a cache hit. To fix
this we first normalize the maps argument to be a tuple of pairs and
always use that as the cache key.

Further we sort the pairs in this tuple to make sure we hit the cache for any
order or pairs parsed to the sparsity constructor. Having a fixed ordering is
also a prerequisite for mixed spaces.

Also verify that each entry in the maps argument is actually of type Map
and add unit test to verify the sparsity caching behavior is as intended.