{-# OPTIONS --without-K #-}
module function.core where

open import level

-- copied from Agda's standard library

infixr 9 _∘'_
infixr 0 _$_

_∘'_ :  {a b c}
      {A : Set a} {B : A  Set b} {C : {x : A}  B x  Set c} 
      (∀ {x} (y : B x)  C y)  (g : (x : A)  B x) 
      ((x : A)  C (g x))
f ∘' g = λ x  f (g x)

const :  {a b} {A : Set a} {B : Set b}  A  B  A
const x = λ _  x

_$_ :  {a b} {A : Set a} {B : A  Set b} 
      ((x : A)  B x)  ((x : A)  B x)
f $ x = f x

flip :  {a b c} {A : Set a} {B : Set b} {C : A  B  Set c} 
       ((x : A) (y : B)  C x y)  ((y : B) (x : A)  C x y)
flip f = λ y x  f x y

record Composition u₁ u₂ u₃ u₁₂ u₂₃ u₁₃
        : Set (lsuc (u₁  u₂  u₃  u₁₂  u₂₃  u₁₃)) where
  infixl 9 _∘_
  field
    U₁ : Set u₁
    U₂ : Set u₂
    U₃ : Set u₃

    hom₁₂ : U₁  U₂  Set u₁₂
    hom₂₃ : U₂  U₃  Set u₂₃
    hom₁₃ : U₁  U₃  Set u₁₃

    _∘_ : {X₁ : U₁}{X₂ : U₂}{X₃ : U₃}  hom₂₃ X₂ X₃  hom₁₂ X₁ X₂  hom₁₃ X₁ X₃

record Identity u e : Set (lsuc (u  e)) where
  field
    U : Set u
    endo : U  Set e
    id : {X : U}  endo X

  id- : (X : U)  endo X
  id- X = id {X}

instance
  func-comp :  {i j k}  Composition _ _ _ _ _ _
  func-comp {i}{j}{k} = record
    { U₁ = Set i
    ; U₂ = Set j
    ; U₃ = Set k
    ; hom₁₂ = λ X Y  X  Y
    ; hom₂₃ = λ X Y  X  Y
    ; hom₁₃ = λ X Y  X  Y
    ; _∘_ = λ f g x  f (g x) }

instance
  func-id :  {i}  Identity _ _
  func-id {i} = record
    { U = Set i
    ; endo = λ X  X  X
    ; id = λ x  x }

module ComposeInterface {u₁ u₂ u₃ u₁₂ u₂₃ u₁₃}
                         comp : Composition u₁ u₂ u₃ u₁₂ u₂₃ u₁₃  where
  open Composition comp public using (_∘_)
open ComposeInterface public

module IdentityInterface {i e}
                          identity : Identity i e  where
  open Identity identity public using (id; id-)
open IdentityInterface public