Configuration for this rule. Create a new one with defaults and use
doNotSortLiterals, sortListPatternsByLength, etc. to alter it.
The default configuration, with the following behavior:
All custom types are sorted. (This can be restricted by using
sortOnlyMatchingTypes.)
Literal patterns (String, Int, etc.) are sorted in the natural order for their type.
Types imported from dependencies are sorted in declaration order, i.e. in the order they appear in the dependency's source file (or more technically in its documentation); this is identical to the behavior of types defined within your own modules.
Lists are sorted elementwise, by comparing the elements sequentially at each position (from left to right).
Unsortable patterns can be looked beyond to resolve ties, for example:
func x =
case x of
T () Bar ->
1
T () Baz ->
2
T () Foo ->
3will be sorted to
func x =
case x of
T () Foo ->
3
T () Bar ->
1
T () Baz ->
2Use doNotSortLiterals, sortListPatternsByLength, etc. to alter any of this
behavior, e.g.
config =
[ NoUnsortedCases.defaults
|> NoUnsortedCases.doNotSortLiterals
|> NoUnsortedCases.sortListPatternsByLength
|> NoUnsortedCases.rule
]Restrict custom type sorting to only those matching a provided predicate.
This function takes two strings, the first being the full module name of a type,
e.g. "Review.Rule" and the second being the name of a type, e.g. "Rule", and
returns a Bool indicating whether the type should be sorted (with True
meaning sortable). For example:
Module Foo:
module Foo exposing (Foo(..))
type Foo
= Foo
| Bar
| BazModule Main:
module Main exposing (..)
type Msg
= ButtonPressed
| ButtonClickedModule ReviewConfig:
onlyMsg moduleName typeName =
case ( moduleName, typeName ) of
( "Main", "Msg" ) ->
True
_ ->
False
config =
[ NoUnsortedCases.defaults
|> NoUnsortedCases.sortOnlyMatchingTypes onlyMsg
|> NoUnsortedCases.rule
]will sort the following pattern:
case msg of
ButtonClicked ->
( { model | clicked = True }, Cmd.none )
ButtonPressed ->
( { model | pressed = True }, Cmd.none )but will not sort:
case foo of
Bar ->
"bar"
Baz ->
"baz"
Foo ->
"foo"Change the behavior of the rule to not sort literal patterns. If literals are not sorted, case expressions that would require sorting literals cannot be sorted and will thus be ignored by the rule.
Do not sort types from dependencies at all. Note that this will render unsortable any patterns requiring types from dependencies to be sorted.
Sort custom types imported from dependencies (including Basics types like Maybe and Bool) alphabetically, rather than by their source order in the dependency's source code.
List patterns may be sorted in one of two ways:
List.sort (which is why it is the default).Note that uncons patterns are considered the length of their matching list, with wildcard patterns considered to have infinite length for the purposes of sorting. This is necessary to ensure that earlier patterns are not erroneously matched by wildcards.
Elementwise
case list of
[] ->
""
[ 1 ] ->
"1"
[ 1, 1 ] ->
"11"
[ 1, 1, 1 ] ->
"111"
[ 1, 2 ] ->
"12"
[ 1, 3 ] ->
"13"
[ 2 ] ->
"2"
[ 2, 1 ] ->
"21"
[ 2, 2 ] ->
"22"
[ 2, 3 ] ->
"23"
[ 3 ] ->
"3"
_ ->
"Too many..."Length First
case list of
[] ->
""
[ 1 ] ->
"1"
[ 2 ] ->
"2"
[ 3 ] ->
"3"
[ 1, 1 ] ->
"11"
[ 1, 2 ] ->
"12"
[ 1, 3 ] ->
"13"
[ 2, 1 ] ->
"21"
[ 2, 2 ] ->
"22"
[ 2, 3 ] ->
"23"
[ 1, 1, 1 ] ->
"111"
_ ->
"Too many..."Do not look beyond unsortable patterns, i.e. do not tiebreak cases with an unsortable sub-pattern by the next sub-pattern.
For example, given this:
type X
= A
| B () Int
f x =
case x of
B () 2 ->
1
B () 1 ->
2
A ->
3By default, this will be sorted to:
case x of
A ->
3
-- v The rule sorted these patterns because even though it can't compare the (), 1 comes before 2
B () 1 ->
2
B () 2 ->
1With doNotLookPastUnsortable, however, the two B patterns will be considered
unsortable, so it will instead be sorted to this:
case x of
A ->
3
-- v Comparison stopped for these patterns because the rule didn't look beyond the ()
B () 2 ->
1
B () 1 ->
2Note that A is sorted above B in both cases because it did not require
comparing the unsortable () pattern.
It's not clear why you'd ever want to use this, so it will likely be removed in a future major version. Please let me know if you actually find it useful!
Reports case patterns that are not in the "proper" order.
🔧 Running with
--fixwill automatically sort the patterns.The proper order of custom types is the order in which they are defined in your source files, and the order of other patterns may be specified in the rule configuration. See the Configuration section below for more information.
Fail
Success
When (not) to enable this rule
This rule is useful when you want to ensure that you pattern match in a consistent, predictable order, that is consistent with the order in which a type was defined, as well as ensuring (optionally) that literal patterns and the like are sorted.
This rule is not useful when you want to be able to write case patterns in different orders throughout your codebase, e.g. if you want to emphasize what pattern is most important at any given point or glean a tiny bit of performance out of matching the more commonly-expected patterns first.
Try it out
You can try this rule out by running the following command: