Comparing 2 things
Always EQ for any 2 things
tie 5555 -12345 --> EQOrder by a transformed value. Examples:
import String.Order
import Char.Order
[ { name = "Bo" }, { name = "Amy" }, { name = "Cam" } ]
|> List.sortWith
(Order.by .name
(String.Order.greaterEarlier (Char.Order.alphabetically Order.tie))
)
--> [ { name = "Amy" }, { name = "Bo" }, { name = "Cam" } ]
{-| `Order` `Tuple.first`, then on tie `Tuple.second`
Order.tuple ( Int.Order.increasing, Int.Order.increasing ) ( 0, 2 ) ( 0, -2 )
--→ GT
-}
tuple : ( Ordering part0, Ordering part1 ) -> Ordering ( part0, part1 )
tuple ( part0Order, part1Order ) =
Order.onTieNext
[ Order.by Tuple.first part0Order
, Order.by Tuple.second part1Order
]import Case
import Char.Order
import Order exposing (Ordering)
import String.Order
type User
= User { name : String }
userNameOrder : Ordering Username
userNameOrder =
Order.by (\(User user) -> user)
(Order.by .name
(String.Order.greaterEarlier (Char.Order.alphabetically Case.lowerUpper))
)type Case
= Lower
| Upper
{-| `'A' < 'a'`
-}
upperLower : Ordering Case
upperLower =
Order.by
(\case_ ->
case case_ of
Upper ->
0
Lower ->
1
)
Int.Order.increasingmodule 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.onTieNext
[ 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
( other0, other1 ) ->
-- sort others according to tag "rank"
Order.by
(\card ->
case card of
Normal _ ->
0
Joker ->
1
)
Int.Order.increasing
other0
other1Use ↑ 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!
a < b ⇆ a > b
import Char.Order
import String.Order
[ "b", "c", "a" ]
|> List.sortWith
(String.Order.greaterEarlier
(Char.Order.alphabetically Order.tie)
)
--> [ "a", "b", "c" ]
[ "b", "c", "a" ]
|> List.sortWith
(String.Order.greaterEarlier
(Char.Order.alphabetically Order.tie)
|> Order.reverse
)
--> [ "c", "b", "a" ]Prioritize the Ordering by one aspect
and break ties with the following
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.onTieNext
[ 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
)
Int.Order.increasingmatthewsj/elm-orderingbyField: byField Tuple.first, ... are also possibleisOrdered, both byField & byFieldWith, ...... |> breakTiesWith ... chain instead of onTieNext [ ... ]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 wantednikita-volkov/: Typeclasses-Classes-Comparisonint,float,comparable & map)HashingContainers.HashSet,
HashingContainers.HashDict
are nice!
How 2 thing compare to each other. An
Orderingcan be used directly tosortWith, make comparisons, ...