Skip to content

Commit bc816b0

Browse files
MatthijsBlomulysses4ever
authored andcommitted
mappend -> <>
1 parent d7833f4 commit bc816b0

3 files changed

Lines changed: 102 additions & 101 deletions

File tree

source_md/a-fistful-of-monads.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ class Monad m => MonadPlus m where
968968
mplus :: m a -> m a -> m a
969969
```
970970

971-
`mzero` is synonymous to `mempty` from the `Monoid` type class and `mplus` corresponds to `mappend`.
971+
`mzero` is synonymous to `mempty` from the `Monoid` type class and `mplus` corresponds to `<>`.
972972
Because lists are monoids as well as monads, they can be made an instance of this type class:
973973

974974
```{.haskell:hs}

source_md/for-a-few-monads-more.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,24 +133,24 @@ However, the type we have now only works for lists.
133133
It seems like we'd have to make a separate `applyLog` for bytestrings.
134134
But wait!
135135
Both lists and bytestrings are monoids.
136-
As such, they are both instances of the `Monoid` type class, which means that they implement the `mappend` function.
137-
And for both lists and bytestrings, `mappend` is for appending.
136+
As such, they are both instances of the `Monoid` type class, which means that they implement the `<>` function.
137+
And for both lists and bytestrings, `<>` is for appending.
138138
Watch:
139139

140140
```{.haskell:hs}
141-
ghci> [1,2,3] `mappend` [4,5,6]
141+
ghci> [1,2,3] <> [4,5,6]
142142
[1,2,3,4,5,6]
143-
ghci> B.pack [99,104,105] `mappend` B.pack [104,117,97,104,117,97]
143+
ghci> B.pack [99,104,105] <> B.pack [104,117,97,104,117,97]
144144
Chunk "chi" (Chunk "huahua" Empty)
145145
```
146146

147147
Cool!
148148
Now our `applyLog` can work for any monoid.
149-
We have to change the type to reflect this, as well as the implementation, because we have to change `++` to `mappend`:
149+
We have to change the type to reflect this, as well as the implementation, because we have to change `++` to `<>`:
150150

151151
```{.haskell:hs}
152152
applyLog :: (Monoid m) => (a,m) -> (a -> (b,m)) -> (b,m)
153-
applyLog (x,log) f = let (y,newLog) = f x in (y,log `mappend` newLog)
153+
applyLog (x,log) f = let (y,newLog) = f x in (y,log <> newLog)
154154
```
155155

156156
Because the accompanying value can now be any monoid value, we no longer have to think of the tuple as a value and a log, but now we can think of it as a value with an accompanying monoid value.
@@ -171,10 +171,10 @@ addDrink _ = ("beer", Sum 30)
171171
```
172172

173173
We use strings to represent foods and an `Int` in a `Sum` `newtype` wrapper to keep track of how many cents something costs.
174-
Just a reminder, doing `mappend` with `Sum` results in the wrapped values getting added together:
174+
Just a reminder, doing `<>` with `Sum` results in the wrapped values getting added together:
175175

176176
```{.haskell:hs}
177-
ghci> Sum 3 `mappend` Sum 9
177+
ghci> Sum 3 <> Sum 9
178178
Sum {getSum = 12}
179179
```
180180

@@ -229,7 +229,7 @@ Its `Monad` instance is defined like so:
229229
```{.haskell:hs}
230230
instance (Monoid w) => Monad (Writer w) where
231231
return x = Writer (x, mempty)
232-
(Writer (x,v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v')
232+
(Writer (x,v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v <> v')
233233
```
234234

235235
![when you have to poop, poop, don't talk](assets/images/for-a-few-monads-more/angeleyes.png){.right width=383 height=248}
@@ -238,15 +238,15 @@ First off, let's examine `>>=`.
238238
Its implementation is essentially the same as `applyLog`, only now that our tuple is wrapped in the `Writer` `newtype`, we have to unwrap it when pattern matching.
239239
We take the value `x` and apply the function `f` to it.
240240
This gives us a `Writer w a` value and we use a `let` expression to pattern match on it.
241-
We present `y` as the new result and use `mappend` to combine the old monoid value with the new one.
241+
We present `y` as the new result and use `<>` to combine the old monoid value with the new one.
242242
We pack that up with the result value in a tuple and then wrap that with the `Writer` constructor so that our result is a `Writer` value instead of just an unwrapped tuple.
243243

244244
So, what about `return`?
245245
It has to take a value and put it in a default minimal context that still presents that value as the result.
246246
So what would such a context be for `Writer` values?
247247
If we want the accompanying monoid value to affect other monoid values as little as possible, it makes sense to use `mempty`.
248248
`mempty` is used to present identity monoid values, such as `""` and `Sum 0` and empty bytestrings.
249-
Whenever we use `mappend` between `mempty` and some other monoid value, the result is that other monoid value.
249+
Whenever we use `<>` between `mempty` and some other monoid value, the result is that other monoid value.
250250
So if we use `return` to make a `Writer` value and then use `>>=` to feed that value to a function, the resulting monoid value will be only what the function returns.
251251
Let's use `return` on the number `3` a bunch of times, only we'll pair it with a different monoid every time:
252252

@@ -271,7 +271,7 @@ The `Writer` instance doesn't feature an implementation for `fail`, so if a patt
271271
Now that we have a `Monad` instance, we're free to use `do` notation for `Writer` values.
272272
It's handy for when we have a several `Writer` values and we want to do stuff with them.
273273
Like with other monads, we can treat them as normal values and the context gets taken for us.
274-
In this case, all the monoid values that come attached get `mappend`ed and so are reflected in the final result.
274+
In this case, all the monoid values that come attached get `<>`ed and so are reflected in the final result.
275275
Here's a simple example of using `do` notation with `Writer` to multiply two numbers:
276276

277277
```{.haskell:hs}
@@ -428,7 +428,7 @@ We just replace normal values with `Writer` values where we want and change norm
428428
### Inefficient list construction
429429

430430
When using the `Writer` monad, you have to be careful which monoid to use, because using lists can sometimes turn out to be very slow.
431-
That's because lists use `++` for `mappend` and using `++` to add something to the end of a list is slow if that list is really long.
431+
That's because lists use `++` for `<>` and using `++` to add something to the end of a list is slow if that list is really long.
432432

433433
In our `gcd'` function, the logging is fast because the list appending ends up looking like this:
434434

@@ -531,14 +531,14 @@ Here's the `Monoid` instance:
531531
```{.haskell:hs}
532532
instance Monoid (DiffList a) where
533533
mempty = DiffList (\xs -> [] ++ xs)
534-
(DiffList f) `mappend` (DiffList g) = DiffList (\xs -> f (g xs))
534+
(DiffList f) <> (DiffList g) = DiffList (\xs -> f (g xs))
535535
```
536536

537-
Notice how for lists, `mempty` is just the `id` function and `mappend` is actually just function composition.
537+
Notice how for lists, `mempty` is just the `id` function and `<>` is actually just function composition.
538538
Let's see if this works:
539539

540540
```{.haskell:hs}
541-
ghci> fromDiffList (toDiffList [1,2,3,4] `mappend` toDiffList [1,2,3])
541+
ghci> fromDiffList (toDiffList [1,2,3,4] <> toDiffList [1,2,3])
542542
[1,2,3,4,1,2,3]
543543
```
544544

@@ -883,7 +883,7 @@ But what goes on in it?
883883
Well, we somehow have to extract the result value from the first stateful computation.
884884
Because we're in a stateful computation right now, we can give the stateful computation `h` our current state `s`, which results in a pair of result and a new state: `(a, newState)`.
885885
Every time so far when we were implementing `>>=`, once we had the extracted the result from the monadic value, we applied the function `f` to it to get the new monadic value.
886-
In `Writer`, after doing that and getting the new monadic value, we still had to make sure that the context was taken care of by `mappend`ing the old monoid value with the new one.
886+
In `Writer`, after doing that and getting the new monadic value, we still had to make sure that the context was taken care of by `<>`ing the old monoid value with the new one.
887887
Here, we do `f a` and we get a new stateful computation `g`.
888888
Now that we have a new stateful computation and a new state (goes by the name of `newState`) we just apply that stateful computation `g` to the `newState`.
889889
The result is a tuple of final result and final state!
@@ -1342,7 +1342,7 @@ ghci> join [[1,2,3],[4,5,6]]
13421342
```
13431343

13441344
As you can see, for lists, `join` is just `concat`.
1345-
To flatten a `Writer` value whose result is a `Writer` value itself, we have to `mappend` the monoid value.
1345+
To flatten a `Writer` value whose result is a `Writer` value itself, we have to `<>` the monoid value.
13461346

13471347
```{.haskell:hs}
13481348
ghci> runWriter $ join (Writer (Writer (1,"aaa"),"bbb"))

0 commit comments

Comments
 (0)