DEV Community

Discussion on: Towards More Effective Software Testing: Equivalence Partitioning and Domain Analysis

Collapse
 
yawaramin profile image
Yawar Amin

I had a little fun implementing the function directly partitioning the inputs by case:

let isLegalMove = (source, dest) => switch (source, dest) {
  | ({suit: Clubs | Spades, rank: sourceRank}, {suit: Hearts | Diamonds, rank: destRank})
  | ({suit: Hearts | Diamonds, rank: sourceRank}, {suit: Clubs | Spades, rank: destRank}) =>
    rankValue(sourceRank) + 1 == rankValue(destRank)
  | _ => false
};
Thread Thread
 
amwzero profile image
Alex Weisberger

That does show the power of pattern matching. You can capture a lot of permutations in a relatively small amount of code this way.

I'm partial to having descriptive names for operations, so I like how the current isLegalMove reads like English: areCardsDifferentColor && areRanksInDescendingOrder reads exactly like the game rules are stated.

That can remain the same and we can use this technique to reimplement areCardsDifferentColor:

let areCardsDifferentColor = (c1, c2) => 
  switch (c1.suit, c2.suit) {
  | (Clubs | Spades, Hearts | Diamonds) => true
  | (Hearts | Diamonds, Clubs | Spades) => true
  | _ => false
  };

It's definitely fun to think about the best way to express things.

Thread Thread
 
yawaramin profile image
Yawar Amin

Yeah, the way you broke down the implementation into helper functions at a lower level of abstraction–the step method–is probably more maintainable overall!