Skip to content

Commit

Permalink
Clean up Basics.Extra (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
gampleman authored Sep 7, 2023
1 parent d95ff26 commit 087ea21
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 271 deletions.
2 changes: 1 addition & 1 deletion docs.json

Large diffs are not rendered by default.

57 changes: 29 additions & 28 deletions src/Basics/Extra.elm
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
module Basics.Extra exposing
( swap
, maxSafeInteger, minSafeInteger, isSafeInteger
, atMost, atLeast
( maxSafeInteger, minSafeInteger, isSafeInteger
, safeDivide, safeIntegerDivide
, safeModBy, safeRemainderBy, fractionalModBy
, safeModBy, safeRemainderBy
, inDegrees, inRadians, inTurns
, flip, curry, uncurry
, orderBy, toOrder, toOrderDesc
, swap, atMost, atLeast, fractionalModBy, orderBy, toOrder, toOrderDesc
)

{-| Additional basic functions.
# Tuples
@docs swap
# Numbers
@docs maxSafeInteger, minSafeInteger, isSafeInteger
# Math
@docs atMost, atLeast
@docs safeDivide, safeIntegerDivide
@docs safeModBy, safeRemainderBy, fractionalModBy
@docs safeModBy, safeRemainderBy
# Angles
Expand All @@ -39,17 +31,24 @@ module Basics.Extra exposing
@docs flip, curry, uncurry
# Comparison & Ordering
# Deprecated functions
These functions are deprecated and **will be removed** in the next major version of this library.
@docs orderBy, toOrder, toOrderDesc
@docs swap, atMost, atLeast, fractionalModBy, orderBy, toOrder, toOrderDesc
-}

import Float.Extra
import Order.Extra


{-| Swaps the elements in a pair.
swap ( 1, 2 ) --> ( 2, 1 )
@deprecated in favour of `Tuple.Extra.flip`.
-}
swap : ( a, b ) -> ( b, a )
swap ( a, b ) =
Expand Down Expand Up @@ -99,6 +98,8 @@ isSafeInteger number =
-42 |> atMost 0 --> -42
@deprecated in favour of `min`
-}
atMost : comparable -> comparable -> comparable
atMost =
Expand All @@ -111,6 +112,8 @@ atMost =
42 |> atLeast 0 --> 42
@deprecated in favour of `max`
-}
atLeast : comparable -> comparable -> comparable
atLeast =
Expand Down Expand Up @@ -220,10 +223,12 @@ in `fractionalModBy modulus x`.
fractionalModBy -2 4.5 == -1.5
@deprecated in favour of `Float.Extra.modBy`
-}
fractionalModBy : Float -> Float -> Float
fractionalModBy modulus x =
x - modulus * toFloat (floor (x / modulus))
fractionalModBy =
Float.Extra.modBy


{-| Convert standard Elm angles (radians) to degrees.
Expand Down Expand Up @@ -318,20 +323,12 @@ to this SQL clause:
ORDER BY tipWidthInMillimeters, model
@deprected in favor of Order.Extra.breakTies
-}
orderBy : List (a -> a -> Order) -> (a -> a -> Order)
orderBy comparators a b =
case comparators of
[] ->
EQ

comparator :: rest ->
case comparator a b of
EQ ->
orderBy rest a b

other ->
other
orderBy =
Order.Extra.breakTies


{-| Helper for multi-dimensional sort.
Expand Down Expand Up @@ -399,6 +396,8 @@ This is primarily a helper function for the `orderBy` function above.
(Note that `List.sortWith colorOrder` above is identical to `List.sortBy colorToComparable`.)
@deprecated in favour of Order.Extra.byField.
-}
toOrder : (a -> comparable) -> (a -> a -> Order)
toOrder selector a b =
Expand Down Expand Up @@ -428,6 +427,8 @@ toOrder selector a b =
[ Yellow, Yellow, Red, Green, Red ]
--> [ Green, Yellow, Yellow, Red, Red ]
@deprecated in favour of `Order.Extra.byField >> Order.Extra.reverse`
-}
toOrderDesc : (a -> comparable) -> (a -> a -> Order)
toOrderDesc selector a b =
Expand Down
26 changes: 26 additions & 0 deletions src/Float/Extra.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Float.Extra exposing
( aboutEqual
, toFixedDecimalPlaces, toFixedSignificantDigits, boundaryValuesAsUnicode
, range
, modBy
)

{-|
Expand All @@ -21,6 +22,11 @@ module Float.Extra exposing
@docs range
# Modular arithmetic
@docs modBy
-}

-- toFixedDecimalDigits implementation
Expand Down Expand Up @@ -385,3 +391,23 @@ range start stop step =
list
in
helper (n - 1) []


{-| Perform [modular arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic)
involving floating point numbers.
The sign of the result is the same as the sign of the `modulus`
in `Float.Extra.modBy modulus x`.
Float.Extra.modBy 2.5 5 --> 0
Float.Extra.modBy 2 4.5 == 0.5
Float.Extra.modBy 2 -4.5 == 1.5
Float.Extra.modBy -2 4.5 == -1.5
-}
modBy : Float -> Float -> Float
modBy modulus x =
x - modulus * toFloat (floor (x / modulus))
53 changes: 51 additions & 2 deletions src/Order/Extra.elm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Order.Extra exposing
( explicit, byField, byFieldWith, byRank, ifStillTiedThen
, breakTiesWith, reverse
, breakTies, breakTiesWith, reverse
, natural
, isOrdered, greaterThanBy, lessThanBy
)
Expand Down Expand Up @@ -82,7 +82,7 @@ to sort a deck of cards you can use `cardOrdering` directly:
# Composition
@docs breakTiesWith, reverse
@docs breakTies, breakTiesWith, reverse
# Strings
Expand Down Expand Up @@ -234,6 +234,55 @@ breakTiesWith tiebreaker mainOrdering x y =
tiebreaker x y


{-| Create an ordering function that can be used to sort
lists by multiple dimensions, by flattening multiple ordering functions into one.
This is equivalent to `ORDER BY` in SQL. The ordering function will order
its inputs based on the order that they appear in the `List (a -> a -> Order)` argument.
type alias Pen =
{ model : String
, tipWidthInMillimeters : Float
}
pens : List Pen
pens =
[ Pen "Pilot Hi-Tec-C Gel" 0.4
, Pen "Morning Glory Pro Mach" 0.38
, Pen "Pilot Hi-Tec-C Coleto" 0.5
]
order : Pen -> Pen -> Order
order =
breakTies [ byField .tipWidthInMillimeters, byField .model ]
List.sortWith order pens
--> [ Pen "Morning Glory Pro Mach" 0.38
--> , Pen "Pilot Hi-Tec-C Gel" 0.4
--> , Pen "Pilot Hi-Tec-C Coleto" 0.5
--> ]
If our `Pen` type alias above was represented a row in a database table, our `order` function as defined above would be equivalent
to this SQL clause:
ORDER BY tipWidthInMillimeters, model
-}
breakTies : List (a -> a -> Order) -> (a -> a -> Order)
breakTies comparators a b =
case comparators of
[] ->
EQ

comparator :: rest ->
case comparator a b of
EQ ->
breakTies rest a b

other ->
other


{-| Produces an ordering defined by an explicit ranking function combined with a
secondary ordering function to compare elements within the same rank. The rule is
that all items are sorted first by rank, and then using the given within-rank
Expand Down
Loading

0 comments on commit 087ea21

Please sign in to comment.