Maintainer | diagrams-discuss@googlegroups.com |
---|

Various monoid-related definitions (monoid actions, split monoids, applicative monoids) used in the core diagrams library.

# Monoid actions

Type class for monoid actions, where monoidal values of type `m`

"act" on values of another type `s`

. Instances are required to
satisfy the laws

act mempty = id

act (m1 `

`mappend`

` m2) = act m1 . act m2

Additionally, if the type `s`

has any algebraic structure, ```
act
m
```

should be a homomorphism. For example, if `s`

is also a
monoid we should have `act m mempty = mempty`

and ```
act m (s1
`
```

.
`mappend`

` s2) = (act m s1) ``mappend`

` (act m s2)

By default, `act = const id`

, so for a monoidal type `M`

which
should have no action on anything, it suffices to write

instance Action M s

with no method implementations.

Action Style m | Styles have no action on other monoids. |

Action Nil l | |

Action Name a | Names don't act on anything else. |

Action Name (NameMap v) | A name acts on a name map by qualifying every name in it. |

Action m n => Action (Split m) n | By default, the action of a split monoid is the same as for the underlying monoid, as if the split were removed. |

Monoid a => Action (SM a) Nil | |

(v ~ V a, HasLinearMap v, Transformable a) => Action (Transformation v) a | Transformations can act on transformable things. |

(Action a a', Action (SM a) l) => Action (SM a) (::: a' l) | |

(Action m n, Foldable f, Functor f, Monoid n) => Action (AM f m) n | An applicative monoid acts on a value of a monoidal type by having each element in the structure act on the value independently, and then folding the resulting structure. |

(Monoid a, Action (SM a) l2, Action l1 l2) => Action (::: a l1) l2 |

# Split monoids

Sometimes we want to accumulate values from some monoid, but have
the ability to introduce a "split" which separates values on
either side. For example, this is used when accumulating
transformations to be applied to primitive diagrams: the `freeze`

operation introduces a split, since only transformations occurring
outside the freeze should be applied to attributes.

A value of type `Split m`

is either a single `m`

, or a pair of
`m`

's separated by a divider.

split :: Monoid m => Split mSource

A convenient name for `mempty :| mempty`

, so `a <> split <> b == a :| b`

.

# Applicative monoids

A wrapper for an `Applicative`

structure containing a monoid.
Such structures have a `Monoid`

instance based on "idiomatic"
application of `mappend`

within the `Applicative`

context.
`instance Monoid m => Monoid (e -> m)`

is one well-known special
case. (However, the standard `Monoid`

instance for `Maybe`

is
*not* an instance of this pattern; nor is the standard instance
for lists.)

AM (f m) |

Functor f => Functor (AM f) | |

Applicative f => Applicative (AM f) | |

(Applicative f, Monoid m) => Monoid (AM f m) | |

(Action m n, Foldable f, Functor f, Monoid n) => Action (AM f m) n | An applicative monoid acts on a value of a monoidal type by having each element in the structure act on the value independently, and then folding the resulting structure. |