module Foo where open import Level record _×_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) where constructor _,_ field fst : A snd : B open _×_ <_,_> : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} → (A → B) → (A → C) → A → (B × C) < f , g > x = (f x , g x) record ⊤ {l} : Set l where constructor tt ! : ∀ {l} {X : Set l} → X → ⊤ {l} ! _ = tt data _+_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) where i₁ : A → A + B i₂ : B → A + B [_,_] : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} → (A → C) → (B → C) → (A + B) → C [ f , g ] (i₁ x) = f x [ f , g ] (i₂ x) = g x data ⊥ {l} : Set l where ¡ : ∀ {l} {X : Set l} → ⊥ {l} → X ¡ () distributeˡ⁻¹ : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} → (A × B) + (A × C) → A × (B + C) distributeˡ⁻¹ (i₁ (x , y)) = (x , i₁ y) distributeˡ⁻¹ (i₂ (x , y)) = (x , i₂ y) distributeˡ : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} → A × (B + C) → (A × B) + (A × C) distributeˡ (x , i₁ y) = i₁ (x , y) distributeˡ (x , i₂ y) = i₂ (x , y) curry : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} → (C × A → B) → C → A → B curry f x y = f (x , y) eval : ∀ {a b} {A : Set a} {B : Set b} → ((A → B) × A) → B eval (f , x) = f x