Your last Uncurry instance is exactly the uncurry (|||)
, so there is nothing "more general" about it.
Curry finds for any arrow f: A×B→C an arrow curryf: A→CB such that a unique arrow eval: CB×B→C commutes. You can view eval as ($)
. Saying "CCC" is the shorthand for "in this category we have all products, all exponents, and a terminal object" - in other words, currying works for any pair of types and any function in haskell. One important consequence of being a CCC is that A=1×A=A×1 (or a
is isomorphic to (a,())
and isomorphic to ((),a)
).
Uncurry in haskell is the opposite labelling of the same process. We start with an arrow f=uncurryg. Each pair has two projections, so a composition of proj1 and curryf=g gives a CB. Since we are talking about composition and products, uncurrying in CCC defines a unique uncurryg for any g: A→CB. In CCC we have all products, so we have CB×B, which can be evaled to C.
In particular, recall A=A×1. This means that any function A→B is also a function A×1→B. You could also view this as "for any function A→B there is a function A×1→B" proven by trivial uncurrying, of which your first instance does only a half (only proves this for id
).
I wouldn't call the last instance a "uncurry" in the same sense as currying is defined. The last instance is a construction of the definition of co-product - for any pair of arrows f: A→C and g: B→C there is a unique arrow [f,g]: (A+B)→C. In this sense it seems as abuse of the interface - it is a generalization of meaning from "uncurry" to "given something, give me something" or "a true correspondence between :->->
and haskell functions". Perhaps, you could rename the class to Arrow.