PROPOSAL: Add Map/IntMap newtypes for different Monoid to containers

Twan van Laarhoven twanvl at gmail.com
Fri Mar 24 15:09:02 UTC 2017


The reason that a newtype is needed is that Map and IntMap are already instances 
of Monoid, with the arguably wrong definition `(<>) = union`. If you want to use 
Map as a monoid with `<> = unionWith (<>)`, you need a newtype.

If we could go back in time, we would just change the Monoid instance for Map 
itself, but that would invisibly break existing code.

Twan

On 2017-03-24 14:03, Nickolay Kudasov wrote:
> Hi Merijn,
>
> I have seen unionWith (<>) used many times and it is indeed a useful operation.
> I also do not recall ever relying on the Monoid instance that's defined currently.
> However, I never needed a newtype wrapper.
> Moreover, introducing a newtype just for the sake of the right Monoid instance
> does not seem to be worth it.
>
> For one I'd want to have all the other useful Map/Set functions (e.g. lookup)
> defined on the newtype to not have to deal with wrapping/unwrapping newtype. So
> for the newtype to really be useful, I guess you would have to copy all the
> functions. I'm guessing this will introduce some maintenance burden.
>
> Besides you can't really add one newtype for all strict/lazy Map/IntMap. Since
> `unionWith` is not a typeclass member, you'd have to resort to 4 (or more)
> newtypes, one for each Map type. And you'd have to copy over all the functions
> for each newtype...
>
> I'd be really happy to see default Monoid instances changed, but I too think
> that's not going to happen (at least anytime soon).
> In the meantime unionWith (<>) seems reasonable enough.
>
> Can you elaborate on how you benefited from a newtype?
> Why unionWith (<>) was not enough?
>
> Kind regards,
> Nick
>
> On Fri, 24 Mar 2017 at 14:39 Merijn Verstraaten <merijn at inconsistent.nl
> <mailto:merijn at inconsistent.nl>> wrote:
>
>     Specifically, it's to add (let's use Foo as non-bikeshed name):
>
>     newtype Foo k v = Foo (Map k v) deriving (...)
>
>     instance (Ord k, Semigroup v) => Semigroup (Foo k v) where
>          Foo m1 <> Foo m2 = Foo (Map.unionWith (<>) m1 m2)
>
>     and corresponding Monoid (which would have 'mempty = Foo Map.empty'),
>     deriving all other instances from Map. And the same for IntMap. I don't
>     particularly care whether the Monoid instance should have a Semigroup or
>     Monoid constraint on 'v'.
>
>     I've personally created this newtype a bunch of times (as have others in
>     #haskell, apparently), but I've never needed/wanted the current Monoid
>     instance. Now I realise that changing the Monoid instance is not happening,
>     so instead I would simply like to add a newtype that has the (to me) more
>     useful Monoid instance.
>
>     Cheers,
>     Merijn
>
>      > On 24 Mar 2017, at 11:59, Andreas Abel <abela at chalmers.se
>     <mailto:abela at chalmers.se>> wrote:
>      >
>      > Please make your proposal more specific.
>      > (So that we can tear it apart, haha!)
>      >
>      > Seriously, I think it is to vague for starting a discussion.
>      >
>      > Best,
>      > Andreas
>      >
>      > On 24.03.2017 11:36, Merijn Verstraaten wrote:
>      >> I would like to propose adding a newtype wrapper (with all relevant
>     instances) for Map and IntMap (if I missed any other applicable type in
>     containers, let me know).
>      >>
>      >> This newtype should differ in Monoid/Semigroup instance from Map/IntMap
>     by switching:
>      >>
>      >> Ord k => Semigroup (Map k v)
>      >> Ord k => Monoid (Map k v)
>      >>
>      >> to:
>      >>
>      >> (Ord k, Semigroup v) => Semigroup (Map k v)
>      >> (Ord k, Monoid v) => Monoid (Map k v) or (Ord k, Semigroup v) => Monoid
>     (Map k v)
>      >>
>      >> Any opinions on the overall idea? Opinions on which Monoid instance?
>     Bikeshed for the newtype names?
>      >>
>      >> Cheers,
>      >> Merijn
>      >>
>      >>
>      >>
>      >> _______________________________________________
>      >> Libraries mailing list
>      >> Libraries at haskell.org <mailto:Libraries at haskell.org>
>      >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>      >>
>      >
>      >
>      > --
>      > Andreas Abel  <><      Du bist der geliebte Mensch.
>      >
>      > Department of Computer Science and Engineering
>      > Chalmers and Gothenburg University, Sweden
>      >
>      > andreas.abel at gu.se <mailto:andreas.abel at gu.se>
>      > http://www.cse.chalmers.se/~abela/
>
>     _______________________________________________
>     Libraries mailing list
>     Libraries at haskell.org <mailto:Libraries at haskell.org>
>     http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
>
>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>


More information about the Libraries mailing list