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

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

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.