Neither.
The teqnique you're looking for is called uncurrying. We know that a function represents a logical implication:
∀ a b. a -> b
We also know that if A and B imply C, then A implies that B implies C:
∀ a b c. ((a, b) => c) <=> (a => b => c)
Here's proof. Look at a truth table for logical implication and you'll see that these are equivalent. So how do you represent A and B
at the type level? You use a product type. The product of two types is a pair, i.e. a type whose values have both of two types:
interface P2<A, B> { public A _1(); public B _2(); }
You can do the same with triples, or tuples of any arity. Beware though, since this line of reasoning leads you to Heterogeneous Lists, which aren't pretty in Java.
Also, your Map
representation is only appropriate for partial functions. What's more, the JDK's Map
interface is designed to be mutable, and whoever heard of a mutable function? Here's a better representation:
interface F<A, B> { public B apply(A a); }