I was ruminating on Semigroups this morning.

In Haskell, a `Semigroup`

is a combination of a *type* and a *function taking two of that type and returning a new one*, where the function is *associative*.

Let’s see if some different things are semigroups:
* `Int`

and `+`

: `(x + y) + z == x + (y + z)`

:heavy_check_mark:
* `Int`

and `*`

: `(x * y) * z == x * (y * z)`

:heavy_check_mark:
* `Int`

and `/`

: `(x / y) / z != x / (y / z)`

:heavy_multiplication_x:
* `String`

and `++`

(concatenation): `(x ++ y) ++ z == x ++ (y ++ z)`

:heavy_check_mark:
* `Maybe String`

and concatenation whenever there is a value:```
(Just "ab" <> Nothing) <> Just "cd" == Just "ab" <> Just "cd" == Just "abcd"
Just "ab" <> (Nothing <> Just "cd") == Just "ab" <> Just "cd" == Just "abcd"
```

:heavy_check_mark:

In Haskell `<>`

generalises all of these operations.

Yesterday @Yura showed us some code like `long "verbose" <> short 'v' <> help "Enable verbose mode"`

Even if you don’t know what type it’s dealing with, you still know it’s joining them all together, and any part of it can be refactored out. So without any anxiety at all, we can change it to

```
let verboseOptions = long "verbose" <> short 'v'
in verboseOptions <> help "Enable verbose mode"
```

Compare with, for example, `joinOptionModifiers (long "verbose") (joinOptionModifiers (short 'v') (help "Enable verbose mode"))`

where you’d have to look up the definition of `joinOptionModifiers`

to know what its return type is, or if it can be refactored in any way.