Redundant cases and redundant case analysis

Code has redundant case analysis if it has either of these two faults:

1. A clause that is (or can be) completely subsumed by another clause or clauses

2. A case analysis that need not be performed

Fault #1 will always be accompanied by overlapping patterns. Fault #2 is independent of overlapping patterns.

Here's an example of Fault #1:

``````fun shiftLeft 0 n = n              (* FAULTY *)
| shiftLeft 1 n = 2 * n
| shiftLeft k n = 2 * shiftLeft (k - 1) n``````

The case for `k = 1` can be handled just as well by the general case:

``````fun shiftLeft 0 n = n              (* CORRECTED *)
| shiftLeft k n = 2 * shiftLeft (k - 1) n``````

Here's an example of Fault #2:

``````fun dropFirstInTwo ([],    [])    = raise Empty   (* FAULTY *)
| dropFirstInTwo ([],    y::ys) = ([], ys)
| dropFirstInTwo (x::xs, [])    = (xs, [])
| dropFirstInTwo (x::xs, y::ys) = (xs, y::ys)``````

In the last two clauses, the case analysis on the second half of the pair is not needed:

``````fun dropFirstInTwo ([],    [])    = raise Empty   (* CORRECTED *)
| dropFirstInTwo ([],    y::ys) = ([], ys)
| dropFirstInTwo (x::xs, ys)    = (xs, ys)``````

In the corrected version, the compiler is doing strictly less work: if the first list is nonempty, the second list doesn't need to be scrutinized.