Definition Has_Exponentials (C : Category) {HP : Has_Products C} :=
∀ a b, (a ⇑ b)%object.
Existing Class Has_Exponentials.
Section Curry_UnCurry.
Context (C : Category) {HP : Has_Products C} {HE : Has_Exponentials C}.
(** Given a arrow f: a×b -> c in a category with exponentials, the curry of f is f̂f^ in the definition of Exponential above. *)
Definition curry :
forall {a b c : C},
(((×ᶠⁿᶜ C) _o (a, b))%object –≻ c) → (a –≻ (HE b c)) :=
fun {a b c : C} (f : ((×ᶠⁿᶜ C) _o (a, b))%object –≻ c) =>
Exp_morph_ex (HE b c) _ f.
(** Given an arrow f: a -> cᵇ, uncurry of f is the arrow (eval_cᵇ ∘ <id_b, f>): a×b -> c. See definition of Exponential above for details. *)
Definition uncurry : forall {a b c : C},
(a –≻ (HE b c)) → (((×ᶠⁿᶜ C) _o (a, b))%object –≻ c) :=
fun {a b c : C} (f : a –≻ (HE b c)) =>
((eval (HE b c)) ∘ ((×ᶠⁿᶜ C) @_a (_, _) (_, _) (f, id C b)))%morphism.
Section inversion.
Context {a b c : C}.

(* Specifications: *)
(** See definition of curry and uncurry above for details. Frollows immediately from the definition of Exponential above. *)
Theorem curry_uncurry (f : a –≻ (HE b c)) : curry (uncurry f) = f.
(** See definition of curry and uncurry above for details. Follows immediately from the definition of Exponential above. *)
Theorem uncurry_curry (f : ((×ᶠⁿᶜ C) _o (a, b))%object –≻ c) :
uncurry (curry f) = f.