import { Kind, $ } from '../../kinds/index.js';
import { None } from '../none';
/**
* A Magma is a set `A` with a binary operation `concat` that is closed on `A`.
*
* Laws:
* - Closure: if a, b ∈ A, then a.b ∈ A
*/
export interface Magma {
concat: (a: A, b: A) => A;
}
/**
* A SemiGroup is a Magma with associativity.
*
* Laws:
* - Associativity: `(a.b).c = a.(b.c)`
*/
export interface SemiGroup extends Magma {
}
export interface FreeSemiGroup extends SemiGroup {
}
export declare namespace SemiGroup {
const checkLaws: (G: SemiGroup) => (a: A, b: A, c: A) => boolean;
}
export interface SemiGroupKind {
semigroup: () => SemiGroup<$>;
}
/**
* Commutative SemiGroup is a SemiGroup with commutativity.
*
* Laws:
* - Commutativity: `a.b = b.a`
*/
export interface CommutativeSemiGroup extends SemiGroup {
}
export declare namespace CommutativeSemiGroup {
const checkLaws: (G: CommutativeSemiGroup) => (a: A, b: A) => boolean;
}
/**
* A Monoid is a SemiGroup with an identity element.
*
* Laws:
* - Identity: if e is the identity element, then `a.e = e.a = a`
*/
export interface Monoid extends SemiGroup {
identity: A;
}
export interface FreeMonoid extends FreeSemiGroup {
identity: Identity;
}
export declare namespace Monoid {
const checkLaws: (G: Monoid) => (a: A) => boolean;
}
export interface MonoidKind extends None {
monoid: () => Monoid<$>;
}
/**
* A Group is a Monoid with invertibility.
*
* Laws:
* - Invertibility: given a, b ∈ A and if b is ther invert of a then `a.b = b.a = e`
*/
export interface Group extends Monoid {
invert: (a: A) => A;
}
export declare namespace Group {
const checkLaws: (G: Group) => (a: A) => boolean;
}
export interface GroupKind extends MonoidKind {
group: () => Group<$>;
}