My knowledge is limited only to c# thus c style languages so i am curious how you would write the contrived conditional statements in the article to be more readable in any other language that would make it more readable than guard clauses
My knowledge is limited only to c# thus c style languages so i am curious how you would write the contrived conditional statements in the article to be more readable in any other language that would make it more readable than guard clauses
getInsuranceAmount status = case
[hasInsurance, isTotaled, isDented, isBigDent ] <*> [status] of
[False, _, _, _ ] -> 1
[True, True, _, _ ] -> 10000
[True, False, False, _ ] -> 0
[True, False, True, True ] -> 270
[True, False, True, False ] -> 160
Personally, I'm not a fan of the early return pattern, since it forces me to read the entire function top to bottom (and possibly simulate a state machine in my head) to understand under what circumstances it returns each possible value, and I'm far too lazy for that.
In contrast, my example makes it very straightforward to see what set of conditions leads to which value, and vice versa.Tangentially, this probably wouldn't be a very idiomatic piece of code to write in Haskell, since some of the conditions are likely to be mutually exclusive (what does it mean when isDented is False but isBigDent is True?) My instinct would be to model the status as a sum type, and then to pattern match on its inhabitants instead of writing helpers for 'hasInsurance,' 'isTotaled,' etc, but someone with proper professional Haskell experience might have an even slicker way to think of it.
if (!status.hasInsurance()){
return 1;
}
if (status.hasInsurance() && status.isTotaled()){
return 10000;
}
// ...
to be explicit about the conditions. Or without early returns but with still the same issue: if (!status.hasInsurance()) {
amount = 1;
} else if (status.isTotaled()) {
amount = 10000;
}
// ... return amount