How should I think about Scala's Product classes?

The package "scala" has a number of classes named Product, Product1, Product2, and so on, up to Product22.

The descriptions of these classes are surely precise. For example:

Product4 is a cartesian product of 4 components

Precise, yes. Communicative? Not so much. I expect that this is the perfect wording for someone who already understands the sense of "cartesian product" being used here. For someone who doesn't, it sounds a bit circular. "Oh yes, well of course Product4 is the mumble product of 4 mumble-mumbles."

Please help me understand the correct functional-language viewpoint. What is the sense of "cartesian product" being used here? What do the Product classes' "projection" members indicate?

19645 次浏览

From this thread:

From mathematics, a Cartesian Product of two sets A, B is denoted as AxB and its elements are (a, b), where a in A and b in B.

For three sets, the elements of the (Cartesian) product are (a, b, c) and so on...

So, you have tuples of elements, and indeed you can see in the Scala library that all the tuples (like Tuple1) inherit the respective product trait (like Product1).

Think of product as the abstraction and the respective tuple a concrete representation.

The projection allows to get the instance of the 'n' class referenced by the Product.

"The set of all possible pairs of elements whose components are members of two sets."

"Specifically, the Cartesian product of two sets X (for example the points on an x-axis) and Y (for example the points on a y-axis), denoted X × Y, is the set of all possible ordered pairs whose first component is a member of X and whose second component is a member of Y (e.g. the whole of the x-y plane)"

Perhaps better understanding can be gained by knowing who derives from it:

Direct Known Subclasses: Tuple4

Or by, knowing it "extends Product", know what other classes can make use of it, by virtue of extending Product itself. I won't quote that here, though, because it's rather long.

Anyway, if you have types A, B, C and D, then Product4[A,B,C,D] is a class whose instances are all possible elements of the cartesian product of A, B, C and D. Literally.

Except, of course, that Product4 is a Trait, not a class. It just provides a few useful methods for classes that are cartesian products of four different sets.

A cartesian product is a product of sets. Given sets A and B, A x B ("A cross B") is the set of all tuples (x, y) such that x is in A and y is in B. A cartesian product may be analogously defined on types: given types A and B, A x B is the type of tuples (x, y) where x is of type A and y is of type B.

So Product4 is the type of tuples (w, x, y, z), where w, x, y, z are components.

Everyone else has gone for the maths so I'll go for the silly answer just in case! You have a simple car which has a gearbox, a steering wheel, an accelerator and a number of passengers. These can each vary: which gear are you in, which way are you steering, is your foot "on the floor" etc. The gearbox, steering, accelerator etc are therefore variables and each has its own set of possible values.

The cartesian product of each of these sets is basically all possible states that your car can be in. So a few possible values are:

(gear,    steer,    accel,     pssngers)
--------|---------|----------|---------
(1st,     left,     foot down, none)
(neutral, straight, off,       the kids)

the size of the cartesian product is of course the product (multiplication) of the possibilities of each set. hence if you car has 5 gears (+ reverse + neutral), steering is left/straight/right, accelerator is on/off and up to 4 passengers, then there are 7 x 3 x 2 x 4 or 168 possible states.

This last fact is the reason that the cartesian product (named after Rene Descartes by the way) has the multiplication symbol x

I think somebody might feel confused for Product just works like a member iterator, just like I did.

In fact, I think in 2019 everybody knows what a Cartesian Product is. But where is Cartesian Product in a Tuple ? I know if we have {a,b,c} and {1,2,3} we'll get {a,1},{a,2}...{c,3}. But when we come across Tuple2(a,1) we just have (a,1), how can one object Product?

So let's treat classes that implement Product as declarations. If class A(String, Int, Double) implentment Product3 , we treat the class as result of a Cartesian Product of (String, Int, Double), thus you know you can use _1 _2 _3method now.