Closed gregwebs closed 9 years ago
Actually, there's more going on here than that. Semigroup
's append operator is <>
, which conflicts with Data.Monoid
. In my code, I use <>
for things which are only Semigroup
instances, ++
for things which are only Monoid
, and for things which are both, it's a crap shoot. However, switching ++
to be list-specific would mean that we either lose the ability to use Semigroup
or lose the Monoid
version. I don't like either option.
I use <>
for anything Semigroup or Monoid and ++
for anything List
. I tend not to distinguish much between Semigroup and Monoid because my main usage of Semigroup is just a non-empty Monoid, so the usage of <>
for either ends up being semantically identical.
We could debate about which approach is better, and I don't care much. The problem is that the current operation is different from the current Haskell Prelude for reasons that no longer matter. What I am proposing (except that you pointed out that <>
is actually for Semigroup and not for Monoid in classy-prelude) is closer to what exists in the Haskell Prelude.
But the breakage may not be worth it.
There are actually some datatypes out there that provide Monoid instances but no Semigroup instances. That's when I'm force to use ++. This proposal would mean I'd have to use mappend instead.
Can you not write instance Semigroup MonoidDataType
first? I am not afraid of using orphans in application code.
I am, I've had plenty of breakage in application code from orphans. They're not as bad as in library code, but it's still a problem. For example, I've had cases where GHC will sometimes successfully compile a module and sometimes not depending on the order of compilation of the modules. If it first compiles the module with the orphan instance, then that instance is in scope, otherwise it isn't.
I guess I should say that with the strategy we use we have no fear. We have separate Instance.hs modules so that the no-orphans warning is off in a limited scope, and those modules have basic imports and are at the root of the import hierarchy because they are essentially Type modules. This ends up giving the same effect as having a foo-instances package.
It might sound like extra work, but once you start the pattern it is easy. I think it is a lot more work to fear orphans.
To each his own. I had to ban orphans almost completely because some people on my team got lazy and started defining orphans for types defined in our own codebase for no good reason at all.
Anyway, I'm a pretty strong -1 on this change. Added to that the breakage as you mentioned, are you OK closing this?
There are 2 existing standards: 1) Prelude <> = Monoid append, ++ = List append 2) Semigroup <> = Semigroup append, ++ = List append
I don't think orphan management is a good reason for classy-prelude to create a new standard.
However, at this point there will probably be too much breakage, so I will have to fix it in antemodulum.
When ++ was generalized to Monoid it made sense because it was right before <> was introduced. Now that we have <>, generalizing ++ means
The only problem now is breaking existing code, which makes this change difficult