Comparing 2 things.
Always EQ independent of the arguments.
Order Ints.
Order.int 40 2
--> GTOrder Floats.
Order.float 0.1 -0.2
--> GTOrder Nothing < Just
Order.maybe Order.int (Just -99999) Nothing
--> GTOrder Lists by elements first to last.
Order.list Order.int
[ 11, 22, 33, 188 ]
[ 11, 22, 34 ]
--> LTOrder Chars.
Order.char { case_ = Order.upperLower } 'b' 'D'
--> LT
Order.char { case_ = Order.upperLower } 'l' 'L'
--> GTOrder Strings by Chars first to last, specifying the Case-Ordering:
Order.string { case_ = Order.lowerUpper }
"hello, human!"
"hello, Human"
--> LTFor string-number chunked text,
you can use mcordova47/: NaturalOrdering.compare
NaturalOrdering.compare "abc2.tff" "abc10.tff"
--→ LTPersonally, I'd just store the String as something like
type TextChunked
= TextChunked ( String, Maybe (List ( Int, String )) )and order that to avoid converting too often.
Case of a Char. Orderings:
'A' < 'a'
'a' < 'A'
Order by a transformed value. Examples:
[ { name = "Bo" }, { name = "Amy" }, { name = "Cam" } ]
|> List.sortWith
(Order.by ( .name, Order.string { case_ = Order.tie } ))
--> [ { name = "Amy" }, { name = "Bo" }, { name = "Cam" } ]import Order exposing (Ordering)
type User
= User { name : String }
userNameOrder : Ordering Username
userNameOrder =
Order.by
( \(User user) -> user
, Order.by ( .name, Order.string { case = Order.lowerUpper } )
)type Case
= Lower
| Upper
{-| `'A' < 'a'`
-}
upperLower : Ordering Case
upperLower =
Order.by
( \case_ ->
case case_ of
Upper ->
0
Lower ->
1
, Order.int
)module Card exposing (Card(..), CardNormal, order)
import Order exposing (Ordering)
import RecordWithoutConstructorFunction exposing (RecordWithoutConstructorFunction)
type Card
= Normal CardNormal
| Joker
type alias CardNormal =
RecordWithoutConstructorFunction
{ value : Value, suite : Suite }
normalOrder : Ordering CardNormal
normalOrder =
Order.downOnTie
[ Order.by ( .suite, suiteOrder )
, Order.by ( .value, valueOrder )
]
order : Ordering Card
order =
\card0 card1 ->
case ( card0, card1 ) of
-- match all variants with _values_
( Normal normal0, Normal normal1 ) ->
normalOrder normal0 normal1
_ ->
-- sort others according to tag "rank"
Order.by
( \card ->
case card of
Normal _ ->
0
Joker ->
1
, Order.int
)
card0
card1Use ↑ once your type union grows to have lots of variants where exhaustive matching has n^2 branches
For simple type unions with only 2 variants:
order : Ordering Card
order =
\card0 card1 ->
case ( card0, card1 ) of
-- match all variants with _values_
( Normal normal0, Normal normal1 ) ->
normalOrder normal0 normal1
( Normal _, Joker ) ->
GT
( Joker, Normal _ ) ->
LT
( Joker, Joker ) ->
EQPretty neat stuff!
Prioritize the Ordering by one aspect
and break ties with the next.
import List.Extra as List
import Order exposing (Ordering)
import RecordWithoutConstructorFunction exposing (RecordWithoutConstructorFunction)
type alias Card =
RecordWithoutConstructorFunction
{ suite : Suite, value : Value }(RecordWithoutConstructorFunction
tricks elm into not creating a Card function)
type Suite
= Clubs
| Hearts
| Diamonds
| Spades
type Value
= Two
| Three
| Four
| Five
| Six
| Seven
| Eight
| Nine
| Ten
| Jack
| Queen
| King
| Ace
cardOrder : Ordering Card
cardOrder =
Order.downOnTie
[ Order.by ( .suite, suiteOrder )
, Order.by ( .value, valueOrder )
]
suiteOrder : Ordering Suite
suiteOrder =
Order.by
( \suite ->
case suite of
Clubs ->
0
Hearts ->
1
Diamonds ->
2
Spades ->
3
, Order.int
)a < b ⇆ a > b
[ "b", "c", "a" ]
|> List.sortWith
(Order.string { case_ = Order.tie })
--> [ "a", "b", "c" ]
[ "b", "c", "a" ]
|> List.sortWith
(Order.string { case_ = Order.tie }
|> Order.reverse
)
--> [ "c", "b", "a" ]matthewsj/elm-orderingbyField: byField Tuple.first, ... are also possibleisOrdered, both byField & byFieldWith, ...... |> breakTiesWith ... chain instead of downOnTie [ ... ]list, maybe, ... orderingsTSFoster/elm-comparelist, maybe, ... compare operationsrtfeldman/elm-sorter-experimenttype → more verboselist, maybe, ... sortersSort.Set & Sort.Dict are very nice! You can even use Sort.Set.empty (Sorter.custom Order.x) if you wanted
An
OrderingtosortWith, make comparisons, and so on: