
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
mailto:merijn@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
mailto:abela@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@haskell.org mailto:Libraries@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@gu.se mailto:andreas.abel@gu.se > http://www.cse.chalmers.se/~abela/ _______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries