# Left-Associative `Semigroup`

Operator Alias

Mailing list discussion in progress on on {libraries,ghc-devs}@haskell.org

related reddit discussion on /r/haskell

## Problem

With the implementation of prime:Libraries/Proposals/SemigroupMonoid, `Semigroup`

will become a superclass of `Monoid`

, and consequently `Semigroup((<>))`

will be re-exported alongside `Monoid`

from the `Prelude`

module.

-- reduced/simplified definition class Semigroup a where (<>) :: a -> a -> a infixr 6 <>

The `infixr 6`

-fixity for `<>`

was already introduced 4 years ago, when we added `Data.Monoid.<>`

as alias for `mappend`

(which differs from `infixr 5 ++`

). See also #3339 for some of the discussion that began in 2009 leading up to the final `infixr 6 <>`

decision.

### Conflicting fixities of `<>`

in pretty printing APIs

However, there are a few popular pretty-printing modules which already define a `<>`

top-level binding for their respective semigroup/monoid binary operation. The problem now is that those `<>`

definitions use a different operator fixity/associativity:

-- pretty module Text.PrettyPrint.Annotated.HughesPJ where infixl 6 <> infixl 6 <+> infixl 5 $$, $+$ -- pretty module Text.PrettyPrint.HughesPJ where infixl 6 <> infixl 6 <+> infixl 5 $$, $+$

-- template-haskell module Language.Haskell.TH.PprLib where infixl 6 <> infixl 6 <+> infixl 5 $$, $+$

-- ghc module Outputable infixl 9 <> infixl 9 <+> infixl 9 $$, $+$ -- ghc module Pretty where infixl 6 <> infixl 6 <+> infixl 5 $$, $+$

On the other hand, the popular hackage:ansi-wl-pprint package does use right-associative operators:

module Text.PrettyPrint.ANSI.Leijen where infixr 6 <> infixr 6 <+>

Other pretty printers also using a `infixr 6 <>, <+>`

definition:

### Changing `<>`

's associativity in pretty-printing APIs

Changing the fixity of `pretty`

's `<>`

would however results in a semantic change for code which relies on the relative fixity between `<+>`

and `<>`

as was pointed out by Duncan back in 2011 already:

So I was preparing to commit this change in base and validating ghc when I discovered a more subtle issue in the pretty package:

Consider

a <> empty <+> bThe fixity of

`<>`

and`<+>`

is critical:(a <> empty) <+> b = {- empty is unit of <> -} (a ) <+> b a <> (empty <+> b) = {- empty is unit of <+> -} a <> ( b)Currently Text.Pretty declares

`infixl 5 <>, <+>`

. If we change them to be`infixr`

then we get the latter meaning of`a <> empty <+> b`

. Existing code relies on the former meaning and produces different output with the latter (e.g. ghc producing error messages like "instancefor" when it should have been "instance for").

### Unsatisfying Situation Seeking a Long-term Solution

Consequently, it's confusing and bad practice to have a soon-to-be-in-Prelude `<>`

operator whose meaning depends on which `import`

s are currently in scope. Moreover, a module needs to combine pretty-printing monoids and other non-pretty-printing monoids, the conflicting `<>`

s operator needs to be disambiguated via module qualification or similiar techniques.

However, there also seems to be a legitimate use-case for a left-associative `<>`

operator.

## Alternative Suggestions

David Terei suggests among other things to

Switch

`<>`

to infixr~~6~~7 and`<+>`

to infixr~~5~~6, some code can still break, but arguably code relying on unintuitive semantics (since somewhat odd`<>`

and`<+>`

have same precedence when both treat empty as identity).

resulting in

infixr 7 <> infixr 6 <+> infixr 5 $$, $+$

## Proposed Solution

Leave `Semigroup((<>))`

as `infixr 6`

, and add a standardised left-associative alias for `<>`

to the `Data.Semigroup`

vocabulary, i.e.

module Data.Semigroup where infixl 6 >< -- | Left-associative alias for (right-associative) 'Semigroup' operation '(<>)' (><) :: Semigroup a => a -> a -> a (><) = (<>)

#### Bikesheds for `><`

`.<>`

`<~>`

`<#>`