ianmackenzie / elm-units / Temperature

Unlike other modules in elm-units, this module contains two different primary types:

Since a Temperature value is not a Quantity, this module exposes specialized functions for doing the operations on Temperature values that do make sense, such as comparing two temperatures or sorting a list of temperatures. It's also possible to find the delta from one temperature to another using minus, and then add a Delta to a Temperature using plus.


type Temperature

A temperature such as 25 degrees Celsius or 80 degrees Fahrenheit.


type alias Delta =
Quantity Basics.Float CelsiusDegrees

A Delta represents the difference between two temperatures.


type CelsiusDegrees

Tempereature deltas are stored as a number of Celsius degrees.

Temperatures

degreesCelsius : Basics.Float -> Temperature

Construct a temperature from a number of degrees Celsius.

inDegreesCelsius : Temperature -> Basics.Float

Convert a temperature to a number of degrees Celsius.

degreesFahrenheit : Basics.Float -> Temperature

Construct a temperature from a number of degrees Fahrenheit.

inDegreesFahrenheit : Temperature -> Basics.Float

Convert a temperature to a number of degrees Fahrenheit.

kelvins : Basics.Float -> Temperature

Construct a temperature from a number of kelvins.

Temperature.kelvins 300
--> Temperature.degreesCelsius 26.85

inKelvins : Temperature -> Basics.Float

Convert a temperature to a number of kelvins.

Temperature.degreesCelsius 0
    |> Temperature.inKelvins
--> 273.15

absoluteZero : Temperature

Absolute zero, equal to zero kelvins or -273.15 degrees Celsius.

Temperature.absoluteZero
--> Temperature.degreesCelsius -273.15

Deltas

Following the suggestion mentioned here, this module uses (for example) celsiusDegrees to indicate a temperature delta (change in temperature), in contrast to degreesCelsius which indicates an actual temperature.

celsiusDegrees : Basics.Float -> Delta

Construct a temperature delta from a number of Celsius degrees.

inCelsiusDegrees : Delta -> Basics.Float

Convert a temperature delta to a number of Celsius degrees.

fahrenheitDegrees : Basics.Float -> Delta

Construct a temperature delta from a number of Fahrenheit degrees.

Temperature.fahrenheitDegrees 36
--> Temperature.celsiusDegrees 20

inFahrenheitDegrees : Delta -> Basics.Float

Convert a temperature delta to a number of Fahrenheit degrees.

Temperature.celsiusDegrees 10
    |> Temperature.inFahrenheitDegrees
--> 18

Constants

Shorthand for Temperature.celsiusDegrees 1 and Temperature.fahrenheitDegrees 1. Can be convenient to use with Quantity.per.

celsiusDegree : Delta

fahrenheitDegree : Delta

Comparison

lessThan : Temperature -> Temperature -> Basics.Bool

Check if one temperature is less than another. Note the argument order!

roomTemperature =
    Temperature.degreesCelsius 21

Temperature.degreesFahrenheit 50
    |> Temperature.lessThan roomTemperature
--> True

-- Same as:
Temperature.lessThan roomTemperature
    (Temperature.degreesFahrenheit 50)
--> True

greaterThan : Temperature -> Temperature -> Basics.Bool

Check if one temperature is greater than another. Note the argument order!

roomTemperature =
    Temperature.degreesCelsius 21

Temperature.degreesFahrenheit 50
    |> Temperature.greaterThan roomTemperature
--> False

-- Same as:
Temperature.greaterThan roomTemperature
    (Temperature.degreesFahrenheit 50)
--> False

lessThanOrEqualTo : Temperature -> Temperature -> Basics.Bool

Check if one temperature is less than or equal to another. Note the argument order!

greaterThanOrEqualTo : Temperature -> Temperature -> Basics.Bool

Check if one temperature is greater than or equal to another. Note the argument order!

compare : Temperature -> Temperature -> Basics.Order

Compare two temperatures, returning an Order value indicating whether the first is less than, equal to or greater than the second.

Temperature.compare
    (Temperature.degreesCelsius 25)
    (Temperature.degreesFahrenheit 75)
--> GT

Temperature.compare
    (Temperature.degreesCelsius 25)
    (Temperature.degreesFahrenheit 77)
--> EQ

(Note that due to floating-point roundoff, you generally shouldn't rely on temperatures comparing as exactly equal.)

equalWithin : Delta -> Temperature -> Temperature -> Basics.Bool

Check if two temperatures are equal within a given delta tolerance. The tolerance must be greater than or equal to zero - if it is negative, then the result will always be false.

Temperature.equalWithin (Temperature.fahrenheitDegrees 1)
    (Temperature.degreesCelsius 25)
    (Temperature.degreesFahrenheit 75)
--> False

Temperature.equalWithin (Temperature.fahrenheitDegrees 3)
    (Temperature.degreesCelsius 25)
    (Temperature.degreesFahrenheit 75)
--> True

min : Temperature -> Temperature -> Temperature

Find the minimum of two temperatures.

Temperature.min
    (Temperature.degreesCelsius 25)
    (Temperature.degreesFahrenheit 75)
--> Temperature.degreesFahrenheit 75

max : Temperature -> Temperature -> Temperature

Find the maximum of two temperatures.

Temperature.max
    (Temperature.degreesCelsius 25)
    (Temperature.degreesFahrenheit 75)
--> Temperature.degreesCelsius 25

Arithmetic

plus : Delta -> Temperature -> Temperature

Add a Delta to a Temperature to get a new Temperature.

Temperature.degreesCelsius 25
    |> Temperature.plus
        (Temperature.celsiusDegrees 7)
--> Temperature.degreesCelsius 32

If you want to subtract a Delta from a Temperature, you can negate the delta first and then call plus.

minus : Temperature -> Temperature -> Delta

Subtract one Temperature from another to get a Delta. Note the argument order!

-- 25 degrees Celsius is 77 degrees Fahrenheit
start =
    Temperature.degreesCelsius 25

end =
    Temperature.degreesFahrenheit 80

end |> Temperature.minus start
--> Temperature.fahrenheitDegrees 3

start |> Temperature.minus end
--> Temperature.fahrenheitDegrees -3

clamp : Temperature -> Temperature -> Temperature -> Temperature

Given a lower and upper bound, clamp a given temperature to within those bounds. Say you wanted to clamp a temperature to be between 18 and 22 degrees Celsius:

lowerBound =
    Temperature.degreesCelsius 18

upperBound =
    Temperature.degreesCelsius 22

Temperature.degreesCelsius 25
    |> Temperature.clamp lowerBound upperBound
--> Temperature.degreesCelsius 22

Temperature.degreesFahrenheit 67 -- approx 19.4 °C
    |> Temperature.clamp lowerBound upperBound
--> Temperature.degreesFahrenheit 67

Temperature.absoluteZero
    |> Temperature.clamp lowerBound upperBound
--> Temperature.degreesCelsius 18

List functions

minimum : List Temperature -> Maybe Temperature

Find the minimum of a list of temperatures. Returns Nothing if the list is empty.

Temperature.minimum
    [ Temperature.degreesCelsius 20
    , Temperature.kelvins 300
    , Temperature.degreesFahrenheit 74
    ]
--> Just (Temperature.degreesCelsius 20)

maximum : List Temperature -> Maybe Temperature

Find the maximum of a list of temperatures. Returns Nothing if the list is empty.

Temperature.maximum
    [ Temperature.degreesCelsius 20
    , Temperature.kelvins 300
    , Temperature.degreesFahrenheit 74
    ]
--> Just (Temperature.kelvins 300)

sort : List Temperature -> List Temperature

Sort a list of temperatures from lowest to highest.

Temperature.sort
    [ Temperature.degreesCelsius 20
    , Temperature.kelvins 300
    , Temperature.degreesFahrenheit 74
    ]
--> [ Temperature.degreesCelsius 20
--> , Temperature.degreesFahrenheit 74
--> , Temperature.kelvins 300
--> ]

sortBy : (a -> Temperature) -> List a -> List a

Sort an arbitrary list of values by a derived Temperature. If you had

rooms =
    [ ( "Lobby", Temperature.degreesCelsius 21 )
    , ( "Locker room", Temperature.degreesCelsius 17 )
    , ( "Rink", Temperature.degreesCelsius -4 )
    , ( "Sauna", Temperature.degreesCelsius 82 )
    ]

then you could sort by temperature with

Temperature.sortBy Tuple.second rooms
--> [ ( "Rink", Temperature.degreesCelsius -4 )
--> , ( "Locker room", Temperature.degreesCelsius 17 )
--> , ( "Lobby", Temperature.degreesCelsius 21 )
--> , ( "Sauna", Temperature.degreesCelsius 82 )
--> ]