open import Agda.Primitive using (Level; lsuc) open import Relation.Binary.PropositionalEquality using (_≡_) variable a : Level A : Set a module FirstAttempt where record Semigroup (A : Set a) : Set a where field _∙_ : A → A → A isAssociative : ∀ (a₁ a₂ a₃ : A) → a₁ ∙ (a₂ ∙ a₃) ≡ (a₁ ∙ a₂) ∙ a₃ record Monoid (A : Set a) : Set a where field semigroup : Semigroup A open Semigroup semigroup public field zero : A isIdentityLeft : ∀ (a : A) → zero ∙ a ≡ a isIdentityRight : ∀ (a : A) → a ∙ zero ≡ a record ContrivedExample (A : Set a) : Set a where field -- first property monoid : Monoid A -- second property; Semigroup is a stand-in. semigroup : Semigroup A operationsEqual : Monoid._∙_ monoid ≡ Semigroup._∙_ semigroup module SecondAttempt where record IsSemigroup {A : Set a} (_∙_ : A → A → A) : Set a where field isAssociative : ∀ (a₁ a₂ a₃ : A) → a₁ ∙ (a₂ ∙ a₃) ≡ (a₁ ∙ a₂) ∙ a₃ record IsMonoid {A : Set a} (zero : A) (_∙_ : A → A → A) : Set a where field isSemigroup : IsSemigroup _∙_ isIdentityLeft : ∀ (a : A) → zero ∙ a ≡ a isIdentityRight : ∀ (a : A) → a ∙ zero ≡ a open IsSemigroup isSemigroup public record Semigroup (A : Set a) : Set a where field _∙_ : A → A → A isSemigroup : IsSemigroup _∙_ record Monoid (A : Set a) : Set a where field zero : A _∙_ : A → A → A isMonoid : IsMonoid zero _∙_ module ThirdAttempt {A : Set a} (_∙_ : A → A → A) where record IsSemigroup : Set a where field isAssociative : ∀ (a₁ a₂ a₃ : A) → a₁ ∙ (a₂ ∙ a₃) ≡ (a₁ ∙ a₂) ∙ a₃ record IsMonoid (zero : A) : Set a where field isSemigroup : IsSemigroup isIdentityLeft : ∀ (a : A) → zero ∙ a ≡ a isIdentityRight : ∀ (a : A) → a ∙ zero ≡ a open IsSemigroup isSemigroup public