Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#6 add volume module #9

Merged
merged 18 commits into from
Oct 7, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions src/Quantity.elm
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module Quantity exposing
( Quantity(..)
, Squared, Rate
, Squared, Cubed, Rate
, zero, infinity, positiveInfinity, negativeInfinity
, lessThan, greaterThan, compare, equalWithin, max, min, isNaN, isInfinite
, negate, plus, minus, product, ratio, scaleBy, divideBy, abs, clamp, squared, sqrt
, negate, plus, minus, product, ratio, scaleBy, divideBy, abs, clamp, squared, sqrt, cubed, cbrt
, round, floor, ceiling, truncate, toFloatQuantity
, sum, minimum, maximum, sort
, per, times, at, at_, inverse
Expand All @@ -17,10 +17,10 @@ module Quantity exposing

# Unit types

The `Squared` and `Rate` units types allow you to build up and work with
The `Squared`, `Cubed` and `Rate` units types allow you to build up and work with
composite units in a fairly flexible way.

@docs Squared, Rate
@docs Squared, Cubed, Rate


# Constants
Expand All @@ -35,7 +35,7 @@ composite units in a fairly flexible way.

# Arithmetic

@docs negate, plus, minus, product, ratio, scaleBy, divideBy, abs, clamp, squared, sqrt
@docs negate, plus, minus, product, ratio, scaleBy, divideBy, abs, clamp, squared, sqrt, cubed, cbrt


# `Int`/`Float` conversion
Expand Down Expand Up @@ -111,6 +111,17 @@ type Squared units
= Squared units


{-| Represents a units type that is the cube of some other units type; for
example, `Meters` is one units type (the units type of a `Length`) and `Cubed
Meters` is another (the units type of an `Volume`). This is useful because some
functions in this module (specifically [`cubed`](Quantity#cubed),
and [`cbrt`](Quantity#cbrt)) "know" about the
`Cubed` type and how to work with it.
-}
type Cubed units
= Cubed units


{-| Represents the units type of a rate or quotient such as a speed (`Rate
Meters Seconds`) or a pressure (`Rate Newtons SquareMeters`). As with `Squared`,
there are several functions that "know" about the `Rate` units type and how to
Expand Down Expand Up @@ -504,6 +515,21 @@ sqrt (Quantity value) =
Quantity (Basics.sqrt value)


{-| Cube a quantity with some `units`, resulting in a new quantity in
`Cubed units.
-}
cubed : Quantity number units -> Quantity number (Cubed units)
cubed (Quantity value) =
Quantity (value * value * value)


{-| Take a quantity in `Cubed units` and return the cube root of that
quantity in plain `units.
-}
cbrt : Quantity Float (Cubed units) -> Quantity Float units
cbrt (Quantity value) =
Quantity (value ^ (1 /3))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For negative values this will give NaN. (i.e. in elm (-8) ^ (1/3) is NaN.)

This may be the desired behaviour but at the very least this should be documented as people may expect this to work for them.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent point @harrysarson, great catch! Given that we don't have direct access to Math.cbrt from JavaScript, I think the implementation should probably be updated to

cbrt (Quantity value) =
    if value >= 0 then
        Quantity (value ^ (1 / 3))
    else
        Quantity -((-value) ^ (1 / 3))

Does that make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrysarson Thanks!



---------- INT/FLOAT CONVERSIONS ----------

Expand Down
131 changes: 131 additions & 0 deletions src/Volume.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
module Volume exposing
( Volume, CubicMeters
, cubicMeters, inCubicMeters
, cubicMillimeters, inCubicMillimeters, cubicCentimeters, inCubicCentimeters
, cubicInches, inCubicInches, cubicFeet, inCubicFeet, cubicYards, inCubicYards
--, milliliter, liter, deciliter
--, usLiquidGallons, usDryGallons, imperialGallons
--, usLiquidQuarts, usDryQuarts, imperialQuarts
--, usLiquidPints, usDryPints, imperialPints
--, usFluidOunces, imperialFluidOunces
)

{-| A `Volume` represents a volume in cubic meters, cubic feet, liters,
US liquid gallons, imperial fluid ounces etc. It is stored as a number of cubic meters.

@docs Volume, CubicMeters


## Metric

@docs cubicMeters, inCubicMeters
@docs cubicMillimeters, inCubicMillimeters, cubicCentimeters, inCubicCentimeters
@docs --@docs milliliters, inMilliliters, liters, etc


## Imperial

@docs cubicInches, inCubicInches, cubicFeet, inCubicFeet, cubicYards, inCubicYards
@docs --@docs usLiquidGallons, usDryGallons, imperialGallons
@docs --@docs usLiquidQuarts, usDryQuarts, imperialQuarts
@docs --@docs usLiquidPints, usDryPints, imperialPints
@docs --@docs usFluidOunces, imperialFluidOunces

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@docs appears twice here, once before and once after the comment.


-}

import Length exposing (Meters)
import Quantity exposing (Quantity(..), Cubed)


{-| -}
type alias CubicMeters =
Cubed Meters


{-| -}
type alias Volume =
Quantity Float CubicMeters


{-| Construct a volume from a number of cubic meters.
-}
cubicMeters : Float -> Volume
cubicMeters numCubicMeters =
Quantity numCubicMeters


{-| Convert a volume to a number of cubic meters.
-}
inCubicMeters : Volume -> Float
inCubicMeters (Quantity numCubicMeters) =
numCubicMeters


{-| Construct a volume from a number of cubic millimeters.
-}
cubicMillimeters : Float -> Volume
cubicMillimeters numCubicMillimeters =
cubicMeters (1.0e-9 * numCubicMillimeters)


{-| Convert a volume to a number of cubic millimeters.
-}
inCubicMillimeters : Volume -> Float
inCubicMillimeters volume =
1.0e9 * inCubicMeters volume


{-| Construct a volume from a number of cubic inches.
-}
cubicInches : Float -> Volume
cubicInches numCubicInches =
cubicMeters (0.0254 * 0.0254 * 0.0254 * numCubicInches)


{-| Convert a volume to a number of cubic inches.
-}
inCubicInches : Volume -> Float
inCubicInches volume =
inCubicMeters volume / (0.0254 * 0.0254 * 0.0254)


{-| Construct a volume from a number of cubic centimeters.
-}
cubicCentimeters : Float -> Volume
cubicCentimeters numCubicCentimeters =
cubicMeters (1.0e-6 * numCubicCentimeters)


{-| Convert a volume to a number of cubic centimeters.
-}
inCubicCentimeters : Volume -> Float
inCubicCentimeters volume =
1.0e6 * inCubicMeters volume


{-| Construct a volume from a number of cubic feet.
-}
cubicFeet : Float -> Volume
cubicFeet numCubicFeet =
cubicMeters (0.3048 * 0.3048 * 0.3048 * numCubicFeet)


{-| Convert a volume to a number of cubic feet.
-}
inCubicFeet : Volume -> Float
inCubicFeet volume =
inCubicMeters volume / (0.3048 * 0.3048 * 0.3048)


{-| Construct a volume from a number of cubic yards.
-}
cubicYards : Float -> Volume
cubicYards numCubicYards =
cubicMeters (0.9144 * 0.9144 * 0.9144 * numCubicYards)


{-| Convert a volume to a number of cubic yards.
-}
inCubicYards : Volume -> Float
inCubicYards volume =
inCubicMeters volume / (0.9144 * 0.9144 * 0.9144)