purescript-deprecated/purescript-maps

Array/List inconsistency in StrMap API

Closed this issue · 3 comments

The StrMap API is inconsistent in it's usage of Lists and Arrays, eg:

toList :: forall a. StrMap a -> L.List (Tuple String a)
keys :: forall a. StrMap a -> Array String
values :: forall a. StrMap a -> L.List a

I think that the API should be focussed on arrays, given that:

  • it's intended usage is for an efficiency binding to the underlying js hash objects
  • the existing implementation of the List functions (eg value) create a temporary array in any case.

On construction it is possible to abstract over the input type, using Foldable. Unfortunately I don't believe it is possible to use Unfoldable to efficiently unpack StrMaps, at least without constructing an internal intermediate data structure with size proportional to the StrMap itself.

Hence, I think these functions:

fromList :: forall a. L.List (Tuple String a) -> StrMap a
fromListWith :: forall a. (a -> a -> a) -> L.List (Tuple String a) -> StrMap a
toList :: forall a. StrMap a -> L.List (Tuple String a)
values :: forall a. StrMap a -> L.List a
unions :: forall a. L.List (StrMap a) -> StrMap a

should be replaced with

fromFoldable :: forall f a. (Foldable f) => f (Tuple String a) -> StrMap a
fromFoldableWith :: forall f a. (Foldable f) => (a -> a -> a) -> f (Tuple String a) -> StrMap a
toArray :: forall a. StrMap a -> Array (Tuple String a)
values :: forall a. StrMap a -> Array a
unions :: forall f a. (Foldable f) => f (StrMap a) -> StrMap a

I will follow up with a PR if this change is considered worthwhile.

👍

I think the Unfoldable approach is possible though, even without the intermediate data structure.

Instead of fromFoldable how about just toStrMap? We use that naming in List for (Foldable f) => f a -> List a (toList I mean).

Instead of fromFoldable how about just toStrMap?

Is it confusing that that toStrMap constructs a map, and toArray/toList decompose one?