How should I think about Scala's Product classes?
ScalaFunctional ProgrammingScala Problem Overview
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?
Scala Solutions
Solution 1 - Scala
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
Solution 2 - Scala
"The set of all possible pairs of elements whose components are members of two sets."
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.
Solution 3 - Scala
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.
Solution 4 - Scala
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.
Solution 5 - Scala
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
_3
method now.