gcd package:monoid-subclasses

This module defines the GCDMonoid subclass of the Monoid class. The GCDMonoid subclass adds the gcd operation which takes two monoidal arguments and finds their greatest common divisor, or (more generally) the greatest monoid that can be extracted with the </> operation from both. The GCDMonoid class is for Abelian, i.e., Commutative monoids.

Non-commutative GCD monoids

Since most practical monoids in Haskell are not Abelian, the GCDMonoid class has three symmetric superclasses:
  • LeftGCDMonoidClass of monoids for which it is possible to find the greatest common prefix of two monoidal values.
  • RightGCDMonoidClass of monoids for which it is possible to find the greatest common suffix of two monoidal values.
  • OverlappingGCDMonoidClass of monoids for which it is possible to find the greatest common overlap of two monoidal values.

Distributive GCD monoids

Since some (but not all) GCD monoids are also distributive, there are three subclasses that add distributivity:
Class of Abelian monoids that allow the greatest common divisor to be found for any two given values. The operations must satisfy the following laws:
gcd a b == commonPrefix a b == commonSuffix a b
Just a' = a </> p && Just b' = b </> p
where p = gcd a b
In addition, the gcd operation must satisfy the following properties: Uniqueness
all isJust
[ a </> c
, b </> c
, c </> gcd a b
]
==>
(c == gcd a b)
Idempotence
gcd a a == a
Identity
gcd mempty a == mempty
gcd a mempty == mempty
Commutativity
gcd a b == gcd b a
Associativity
gcd (gcd a b) c == gcd a (gcd b c)
Class of commutative GCD monoids with symmetric distributivity. In addition to the general GCDMonoid laws, instances of this class must also satisfy the following laws:
gcd (a <> b) (a <> c) == a <> gcd b c
gcd (a <> c) (b <> c) == gcd a b <> c
Class of left GCD monoids with left-distributivity. In addition to the general LeftGCDMonoid laws, instances of this class must also satisfy the following law:
commonPrefix (a <> b) (a <> c) == a <> commonPrefix b c
Class of monoids capable of finding the equivalent of greatest common divisor on the left side of two monoidal values. The following laws must be respected:
stripCommonPrefix a b == (p, a', b')
where p = commonPrefix a b
Just a' = stripPrefix p a
Just b' = stripPrefix p b
p == commonPrefix a b && p <> a' == a && p <> b' == b
where (p, a', b') = stripCommonPrefix a b
Furthermore, commonPrefix must return the unique greatest common prefix that contains, as its prefix, any other prefix x of both values:
not (x `isPrefixOf` a && x `isPrefixOf` b) || x `isPrefixOf` commonPrefix a b
and it cannot itself be a suffix of any other common prefix y of both values:
not (y `isPrefixOf` a && y `isPrefixOf` b && commonPrefix a b `isSuffixOf` y)
In addition, the commonPrefix operation must satisfy the following properties: Idempotence
commonPrefix a a == a
Identity
commonPrefix mempty a == mempty
commonPrefix a mempty == mempty
Commutativity
commonPrefix a b == commonPrefix b a
Associativity
commonPrefix (commonPrefix a b) c
==
commonPrefix a (commonPrefix b c)
Class of monoids for which the greatest overlap can be found between any two values, such that
a == a' <> overlap a b
b == overlap a b <> b'
The methods must satisfy the following laws:
stripOverlap a b == (stripSuffixOverlap b a, overlap a b, stripPrefixOverlap a b)
stripSuffixOverlap b a <> overlap a b == a
overlap a b <> stripPrefixOverlap a b == b
The result of overlap a b must be the largest prefix of b and suffix of a, in the sense that it contains any other value x that satifies the property (x isPrefixOf b) && (x isSuffixOf a):
∀x. (x `isPrefixOf` b && x `isSuffixOf` a) => (x `isPrefixOf` overlap a b && x `isSuffixOf` overlap a b)
and it must be unique so there's no other value y that satisfies the same properties for every such x:
∀y. ((∀x. (x `isPrefixOf` b && x `isSuffixOf` a) => x `isPrefixOf` y && x `isSuffixOf` y) => y == overlap a b)
In addition, the overlap operation must satisfy the following properties: Idempotence
overlap a a == a
Identity
overlap mempty a == mempty
overlap a mempty == mempty
Class of right GCD monoids with right-distributivity. In addition to the general RightGCDMonoid laws, instances of this class must also satisfy the following law:
commonSuffix (a <> c) (b <> c) == commonSuffix a b <> c
Class of monoids capable of finding the equivalent of greatest common divisor on the right side of two monoidal values. The following laws must be respected:
stripCommonSuffix a b == (a', b', s)
where s = commonSuffix a b
Just a' = stripSuffix p a
Just b' = stripSuffix p b
s == commonSuffix a b && a' <> s == a && b' <> s == b
where (a', b', s) = stripCommonSuffix a b
Furthermore, commonSuffix must return the unique greatest common suffix that contains, as its suffix, any other suffix x of both values:
not (x `isSuffixOf` a && x `isSuffixOf` b) || x `isSuffixOf` commonSuffix a b
and it cannot itself be a prefix of any other common suffix y of both values:
not (y `isSuffixOf` a && y `isSuffixOf` b && commonSuffix a b `isPrefixOf` y)
In addition, the commonSuffix operation must satisfy the following properties: Idempotence
commonSuffix a a == a
Identity
commonSuffix mempty a == mempty
commonSuffix a mempty == mempty
Commutativity
commonSuffix a b == commonSuffix b a
Associativity
commonSuffix (commonSuffix a b) c
==
commonSuffix a (commonSuffix b c)