monoid-extras-0.4.2: Various extra monoid-related definitions and utilities

Copyright(c) 2011 diagrams-core team (see LICENSE)
LicenseBSD-style (see LICENSE)
Safe HaskellSafe



Monoid and semigroup actions.



class Action m s where #

Type class for monoid (and semigroup) 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

Semigroup instances are required to satisfy the second law but with (<>) instead of mappend. 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 type M which should have no action on anything, it suffices to write

instance Action M s

with no method implementations.

It is a bit awkward dealing with instances of Action, since it is a multi-parameter type class but we can't add any functional dependencies---the relationship between monoids and the types on which they act is truly many-to-many. In practice, this library has chosen to have instance selection for Action driven by the first type parameter. That is, you should never write an instance of the form Action m SomeType since it will overlap with instances of the form Action SomeMonoid t. Newtype wrappers can be used to (awkwardly) get around this.


act :: m -> s -> s #

Convert a value of type m to an action on s values.


Action () l #

() acts as the identity.


act :: () -> l -> l #

Action m s => Action (Option m) s #

Nothing acts as the identity; Just m acts as m.


act :: Option m -> s -> s #

Action (Endo a) a #

Endo acts by application.

Note that in order for this instance to satisfy the Action laws, whenever the type a has some sort of algebraic structure, the type Endo a must be considered to represent homomorphisms (structure-preserving maps) on a, even though there is no way to enforce this in the type system. For example, if a is an instance of Monoid, then one should only use Endo a values f with the property that f mempty = mempty and f (a <> b) = f a <> f b.


act :: Endo a -> a -> a #

Action (SM a) () # 


act :: SM a -> () -> () #

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.


act :: Split m -> n -> n #

(Action a a', Action (SM a) l) => Action (SM a) (Option a', l) # 


act :: SM a -> (Option a', l) -> (Option a', l) #

(Action m r, Action n r) => Action ((:+:) m n) r #

Coproducts act on other things by having each of the components act individually.


act :: (m :+: n) -> r -> r #