Credence.Pattern.NoCaseTupleGuardDispatch
(credence v0.7.1)
Copy Markdown
Detects case on a tuple of variables where every clause's pattern
is the same tuple of the same variables — all dispatch is via guards.
This is a cond in disguise.
Bad
case {e1, e2} do
{e1, e2} when e1 < e2 -> advance_left(rest1, list2)
{e1, e2} when e1 > e2 -> advance_right(list1, rest2)
{e1, e2} -> advance_both(rest1, rest2)
endGood
cond do
e1 < e2 -> advance_left(rest1, list2)
e1 > e2 -> advance_right(list1, rest2)
true -> advance_both(rest1, rest2)
endAuto-fix
Unwraps the tuple, extracts guards, and rewrites as cond.
A trailing _ wildcard (or a final guardless tuple clause) is
converted to true.
Safety — why this is narrowed
Moving a when guard into a cond condition is not generally
behaviour-preserving:
- Guards swallow errors:
when hd(a) > 0treats a raised error as a failed clause, but the same expression as acondcondition propagates the error. So we only fire when every guard is built from operators that can never raise — the boolean connectives (and/or/not) over the total comparison operators (==,!=,===,!==,<,>,<=,>=) whose operands are bare variables or literals. Term comparison is total, so these are bit-identical in a guard and in an expression, and they always yield a real boolean (so guard-truth andcond-truthiness agree). - A guard-only
casewith no catch-all raisesCaseClauseError, while the correspondingcondraisesCondClauseError. So we only fire when the final clause is a guardless catch-all (_or the full tuple), making both constructs total over the same inputs.