From 89282aafa38604cf96b0d341339fbb7472e6db23 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sun, 12 May 2024 14:45:44 -0700 Subject: [PATCH] get site docs building again --- build.sbt | 4 - docs/README.md | 10 +- docs/coulomb-core.md | 260 +++++-------------------------------- docs/coulomb-parser.md | 7 +- docs/coulomb-pureconfig.md | 23 +--- docs/coulomb-refined.md | 37 +----- docs/coulomb-runtime.md | 6 +- docs/coulomb-spire.md | 134 ------------------- docs/coulomb-units.md | 30 ++--- docs/develop.md | 2 - 10 files changed, 61 insertions(+), 452 deletions(-) delete mode 100644 docs/coulomb-spire.md diff --git a/build.sbt b/build.sbt index e65e37f50..323fd9509 100644 --- a/build.sbt +++ b/build.sbt @@ -257,10 +257,6 @@ lazy val docs = project "coulomb-units", VirtualPath.parse("coulomb-units.md") ), - TargetDefinition.internal( - "coulomb-spire", - VirtualPath.parse("coulomb-spire.md") - ), TargetDefinition.internal( "coulomb-refined", VirtualPath.parse("coulomb-refined.md") diff --git a/docs/README.md b/docs/README.md index 7957f3b95..c0a91f3fa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,13 +28,8 @@ Import `coulomb` definitions: import coulomb.* import coulomb.syntax.* -// algebraic definitions +// algebraic typeclass definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit and value type policies for operations -import coulomb.policy.standard.given -import scala.language.implicitConversions // unit definitions import coulomb.units.si.{*, given} @@ -47,7 +42,7 @@ Use `coulomb` to do typelevel unit analysis in Scala! val a = 9.8.withUnit[Meter / (Second ^ 2)] // time or duration -val t = 10.withUnit[Second] +val t = 10.0.withUnit[Second] // velocity val v = a * t @@ -73,7 +68,6 @@ val fail = time + dist | ---: | :--- | | [coulomb-core] | Provides core `coulomb` logic. Defines policies for `Int`, `Long`, `Float`, `Double`. | | [coulomb-units] | Defines common units, including SI, MKSA, Accepted, time, temperature, and US traditional | -| [coulomb-spire] | Defines policies for working with Spire and Scala numeric types | | [coulomb-refined] | Unit analysis with typelevel [refined](https://github.com/fthomas/refined#refined-simple-refinement-types-for-scala) awareness | | [coulomb-pureconfig] | Configuration I/O with @:api(coulomb.Quantity$) values | | [coulomb-runtime] | Runtime units and quantities | diff --git a/docs/coulomb-core.md b/docs/coulomb-core.md index 8079252c4..28d0dca24 100644 --- a/docs/coulomb-core.md +++ b/docs/coulomb-core.md @@ -13,11 +13,6 @@ import coulomb.syntax.* // algebraic definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit and value type policies for operations -import coulomb.policy.standard.given -import scala.language.implicitConversions // unit definitions import coulomb.units.si.{*, given} @@ -168,8 +163,8 @@ These are referred to as derived units, or compound units. object nautical: import coulomb.define.* - export coulomb.units.si.{ Meter, ctx_unit_Meter } - export coulomb.units.time.{ Hour, ctx_unit_Hour } + export coulomb.units.si.{ Meter, unit_Meter } + export coulomb.units.time.{ Hour, unit_Hour } final type NauticalMile given unit_NauticalMile: DerivedUnit[NauticalMile, 1852 * Meter, "nmile", "nmi"] = @@ -269,6 +264,22 @@ val w2 = Wrapper(37D).withUnit[Vector[Int]] w2.show ``` +### Numeric Value Types + +The coulomb core libraries provide support for the following numeric types: + +| Value Type | Defined In | +| --- | --- | +| Int | Scala | +| Long | Scala | +| Float | Scala | +| Double | Scala | +| BigInt | Scala | +| BigDecimal | Scala | +| Rational | Spire | +| Algebraic | Spire | +| Real | Spire | + ### Value Types and Algebras Although value and unit types are arbitrary for a `Quantity`, there is no free lunch. @@ -335,41 +346,6 @@ v === v v =!= v ``` -## Truncating Operations - -Some operations involving integral types such as `Int`, `Long`, or `BigInt`, -are considered "truncating" - they lose the fractional component of the result. -In coulomb these are distinguished with specific "truncating" operators: - -```scala mdoc -// fractional values (Double, Float, BigDecimal, Rational, etc) -val fractional = 10.5.withUnit[Meter] - -// truncating value conversions (fractional -> integral) -val integral = fractional.tToValue[Int] - -// truncating unit conversions -integral.tToUnit[Yard] - -// truncating division -integral `tquot` 3 - -// truncating power -integral.tpow[1/2] -``` - -Non-truncating operations are defined in cases where the result will not discard fractional components: -```scala mdoc -// "normal" (aka truncating) operations work when fractional component of results are preserved -fractional / 3 -``` - -Non-truncating operations are undefined on types that would cause truncation. -```scala mdoc:fail -// standard division is undefined for cases that would truncate -integral / 3 -``` - ## Value and Unit Conversions In `coulomb`, a `Quantity[V, U]` may experience conversions along two possible axes: @@ -393,22 +369,6 @@ This is because the best way of converting from unit `UF` to `UT` will depend on You can look at examples of unit conversions defined in `coulomb-core` [here](https://www.javadoc.io/doc/com.manyangled/coulomb-docs_3/latest/coulomb/conversion/standard/unit$.html). -### truncating conversions - -As we saw in -[previous sections][Truncating Operations], -some operations on coulomb quantities may result in "truncation" - the loss of fractional parts of values. -As with operations, truncating conversions are represented by distinct conversions -`TruncatingValueConversion[VF, VT]` and `TruncatingUnitConversion[V, UF, UT]`. - -```scala mdoc -// a truncating value conversion (fractional -> integral) -val qi = q.tToValue[Int] - -// a truncating unit conversion (on an integral type) -qi.tToUnit[Yard] -``` - ### implicit conversions In Scala 3, implicit conversions are represented by `scala.Conversion[F, T]`, @@ -417,30 +377,28 @@ which you can read more about The `coulomb-core` library [pre-defines](https://www.javadoc.io/doc/com.manyangled/coulomb-docs_3/latest/coulomb/conversion/standard/scala$.html) -such implicit conversions, -based on ValueConversion and UnitConversion context in scope. -By convention, `coulomb` performs value conversions first, then unit conversions. +implicit unit conversions, +based on `UnitConversion` context in scope. Implicit quantity conversions can be used in typical Scala scenarios: ```scala mdoc -// implicitly convert double to float, and then cubic meters to liters -val iconv: Quantity[Float, Liter] = 1.0.withUnit[Meter ^ 3] -``` +import scala.language.implicitConversions +import coulomb.conversion.implicits.given -However, numeric operators in `coulomb` may also make use of these implicit conversions: -```scala mdoc -val q1 = 1d.withUnit[Second] -val q2 = 1.withUnit[Minute] +// implicitly convert cubic meters to liters +val iconv: Quantity[Double, Liter] = 1.0.withUnit[Meter ^ 3] -// in this operation, q2's integer value is implicitly converted to double, -// and then minutes are converted to seconds, and added to q1: -q1 + q2 +// implicitly convert "raw" values to unitless Quantity +val uq: Quantity[Int, 1] = 100 ``` -### defining conversions +@:callout(info) +Implicit value conversions are not supported by the coulomb library. +@:@ -The `coulomb-core` and `coulomb-spire` libraries define value and unit conversions for a wide variety of +### defining conversions +The `coulomb-core` libraries define value and unit conversions for a wide variety of popular numeric types, however you can also easily define your own. ```scala mdoc @@ -464,69 +422,6 @@ wq.toUnit[Second] wq.toValue[Wrapper[Float]] ``` -## Value Promotion and Resolution - -We saw in our -[earlier example][implicit conversions] -that `coulomb` can perform implicit value and unit conversions when doing numeric operations. -The high level logic (implemented in chained context rules) is: - -1. "Resolve" left and right value types (`VL` and `VR`) into a final output type `VO` -1. Apply implicit conversion `Quantity[VL, UL]` -> `Quantity[VO, UL]` -1. Apply implicit conversion `Quantity[VR, UR]` -> `Quantity[VO, UL]` -1. Perform the relevant algebraic operation, in value space `VO` -1. Return the resulting value as `Quantity[VO, UL]` - -Note that not all numeric operations require all of these steps, -however here is an example fragment of such code for addition which demonstrates them all: - -```scala -transparent inline given ctx_add_2V2U[VL, UL, VR, UR](using - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveSemigroup[vres.VO] - ): Add[VL, UL, VR, UR] = - new infra.AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) -``` - -In the example above, you can see that the context object that maps -`(VL, VR) => VO` is of type `ValueResolution[VL, VR]`. - -It is possible to define all the necessary `ValueResolution[VL, VR]` for all possible pairs of -`(VL, VR)`, however for more than a small number of such types the number of pairs grows unwieldy -rather fast (quadratically fast in fact). -However, there is another preferred alternative that allows you to only define "key" pairs that -define a Directed Acyclic Graph, and the `coulomb` typeclass system will efficiently search this -space to identify the correct value of `ValueResolution[VL, VR]` at compile time. - -Here is one example that captures the "total ordering" relation among value type resolutions -for `{Int, Long, Float, Double}` that comes with `coulomb-core`: - -```scala -// ValuePromotion infers the transitive closure of all promotions -given ctx_vpp_standard: ValuePromotionPolicy[ - (Int, Long) &: (Long, Float) &: (Float, Double) &: TNil -] = ValuePromotionPolicy() -``` - -Using this, we can finish off our `Wrapper` example with some rules for generating `ValueResolution`. - -```scala mdoc -object wrappervr: - import coulomb.ops.* - transparent inline given vr_Wrapper[VL, VR](using vres: ValueResolution[VL, VR]): ValueResolution[Wrapper[VL], Wrapper[VR]] = - new ValueResolution[Wrapper[VL], Wrapper[VR]]: - type VO = Wrapper[vres.VO] - -import wrappervr.given - -val wq1 = Wrapper(1d).withUnit[Second] -val wq2 = Wrapper(1f).withUnit[Minute] - -wq1 + wq2 -``` - ## Temperature and Time The `coulomb-units` library defines units for temperature and time. @@ -538,7 +433,10 @@ and units of duration. Consider the following example: ```scala mdoc +// import temperature units import coulomb.units.temperature.{*, given} +// import extensions for temp and time +import coulomb.units.syntax.* // Here are two absolute temperatures val cels1 = 10d.withTemperature[Celsius] @@ -606,93 +504,3 @@ DeltaUnit - DeltaUnit => Quantity DeltaUnit + Quantity => DeltaUnit DeltaUnit - Quantity => DeltaUnit ``` - -## Coulomb Policies - -The `coulomb-core` library is designed so that very few typeclasses are hard-coded. -As previous sections demonstrate, it is relatively easy to implement your own typeclasses -if you need to work with custom types, or would prefer behaviors that are different than -available out-of-box typeclasses. - -However, one tradeoff is that to obtain out-of-box features, -the programmer needs to import a somewhat unweildy number of typeclasses. - -To help reduce the number of imports and make it easier to understand various behavior options, -`coulomb` takes advantage of the new Scala 3 -[export clauses](https://docs.scala-lang.org/scala3/reference/other-new-features/export.html) -to provide predefined groupings of imports which represent different "policies" for behavior. - -The `coulomb-core` library defines two policies, which you can import from `coulomb.policy`. -The first, which is used by most of the examples in this documentation, is `coulomb.policy.standard`. -This policy supports: - -- implicit value type promotions -- implicit unit conversions -- implicit value conversions - -Here is an example of using `coulomb.policy.standard` - -```scala mdoc:nest -// note this does not include other necessary imports -import coulomb.policy.standard.given -import scala.language.implicitConversions - -val q1 = 1d.withUnit[Liter] -val q2 = 1.withUnit[Meter ^ 3] - -// with "standard" policy, coulomb can resolve differing value types and unit types -q1 + q2 -``` - -```scala mdoc:reset:invisible -// here we are resetting the compile context -// to demonstrate strict policy - -// fundamental coulomb types and methods -import coulomb.* -import coulomb.syntax.* - -// algebraic definitions -import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit definitions -import coulomb.units.si.{*, given} -import coulomb.units.mksa.{*, given} -import coulomb.units.time.{*, given} -import coulomb.units.accepted.{*, given} -``` - -The second pre-defined policy is `couomb.policy.strict`, -which does *not* allow implicit conversions of values or units. -Operations involving identical value and unit types are always allowed, -as are *explicit* conversions: - -```scala mdoc -import coulomb.policy.strict.given - -val q1 = 1d.withUnit[Liter] -val q2 = 2d.withUnit[Liter] - -// strict policy allows operating with same unit and value -q1 + q2 - -// explicit value and unit conversions are always allowed -q1.toValue[Float] -q1.toUnit[Meter ^ 3] -``` - -```scala mdoc:fail -val q3 = 1.withUnit[Meter ^ 3] - -// strict policy does not allow implicit value or unit conversions -q1 + q3 -``` - -The `coulomb-spire` library provides additional predefined policies that -support the standard Scala numeric types as well as spire's specialized types. - -@:callout(info) -If you import `coulomb-spire` policies, do not also import `coulomb-core` policies. -Only one policy at a time should be imported. -@:@ diff --git a/docs/coulomb-parser.md b/docs/coulomb-parser.md index c4f757df5..db152bdd2 100644 --- a/docs/coulomb-parser.md +++ b/docs/coulomb-parser.md @@ -29,11 +29,6 @@ import coulomb.syntax.* // algebraic definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit and value type policies for operations -import coulomb.policy.standard.given -import scala.language.implicitConversions // unit definitions import coulomb.units.si.{*, given} @@ -43,7 +38,7 @@ import coulomb.units.time.{*, given} // parsing definitions import coulomb.parser.RuntimeUnitParser -import coulomb.parser.standard.RuntimeUnitDslParser +import coulomb.parser.dsl.RuntimeUnitDslParser ``` ### examples diff --git a/docs/coulomb-pureconfig.md b/docs/coulomb-pureconfig.md index 760ad29d1..537a4f8c8 100644 --- a/docs/coulomb-pureconfig.md +++ b/docs/coulomb-pureconfig.md @@ -45,11 +45,6 @@ import coulomb.syntax.* // algebraic definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit and value type policies for operations -import coulomb.policy.standard.given -import scala.language.implicitConversions // unit definitions import coulomb.units.si.prefixes.{*, given} @@ -57,10 +52,10 @@ import coulomb.units.info.{*, given} import coulomb.units.time.{*, given} // pureconfig defs -import _root_.pureconfig.{*, given} +import pureconfig.{*, given} // import basic coulomb-pureconfig defs -import coulomb.pureconfig.* +import coulomb.integrations.pureconfig.* ``` ### examples @@ -116,7 +111,7 @@ automatically convert compatible units, and load successfully. ```scala mdoc // use the DSL-based io definitions for RuntimeUnit objects -import coulomb.pureconfig.policy.DSL.given +import coulomb.integrations.pureconfig.DSL.given // define a configuration source // this source uses units that are different than the Config type @@ -165,9 +160,6 @@ if the conversion factor is exactly 1. @:callout(info) The safest way to ensure unit conversions will always succeed is to use fractional value types such as Float or Double. -If desired, -[coulomb-spire](coulomb-spire.md) -provides integrations for fractional value types of higher precision. @:@ ```scala mdoc @@ -205,14 +197,11 @@ but it is more amenable to explicitly structured expressions. import coulomb.* import coulomb.syntax.* import algebra.instances.all.given -import coulomb.ops.algebra.all.given -import coulomb.policy.standard.given -import scala.language.implicitConversions import coulomb.units.si.prefixes.{*, given} import coulomb.units.info.{*, given} import coulomb.units.time.{*, given} -import _root_.pureconfig.{*, given} -import coulomb.pureconfig.* +import pureconfig.{*, given} +import coulomb.integrations.pureconfig.* given given_pureconfig: PureconfigRuntime = PureconfigRuntime.of[ "coulomb.units.si.prefixes" *: @@ -242,7 +231,7 @@ given given_ConfigLoader(using ```scala mdoc // use the JSON-based io definitions for RuntimeUnit objects -import coulomb.pureconfig.policy.JSON.given +import coulomb.integrations.pureconfig.JSON.given // this configuration source represents units in structured JSON val source = ConfigSource.string(""" diff --git a/docs/coulomb-refined.md b/docs/coulomb-refined.md index c301d95ea..2b062df7f 100644 --- a/docs/coulomb-refined.md +++ b/docs/coulomb-refined.md @@ -36,17 +36,12 @@ import eu.timepit.refined.numeric.* // algebraic definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.{*, given} - -// standard policy for spire and scala types -import coulomb.policy.standard.given -import scala.language.implicitConversions // overlay policy for refined integrations -import coulomb.policy.overlay.refined.algebraic.given +import coulomb.integrations.refined.all.given // coulomb syntax for refined integrations -import coulomb.syntax.refined.* +import coulomb.integrations.refined.syntax.* ``` ### examples @@ -116,34 +111,6 @@ pe1 + pe1 pe1 + pe2 ``` -## Policies - -### policy overlays - -The `coulomb-refined` package currently provides a single "overlay" policy. -An overlay policy is designed to work with any other policies currently in scope, -and lift them into another abstraction; -in this case, lifting policies for value type(s) `V` into `Refined[V, P]`. -The `Refined` abstraction guarantees that a value of type `V` satisfies some predicate `P`, -and the semantics of `V` remain otherwise unchanged. - -For example, given any algebra in scope for a type `V` that defines addition, -the `coulomb-refined` overlay defines the corresponding `Refined[V, P]` addition -like so: -```scala -plus(x: Refined[V, P], y: Refined[V, P]): Refined[V, P] = -// (x.value + y.value) refined by P -``` - -@:callout(info) -Because the refined algebraic policy is an overlay, -you can use it with your choice of base policies, -for example with -[core policies](coulomb-core.md#coulomb-policies) -or -[spire policies](coulomb-spire.md#policies). -@:@ - ### algebraic policy table The following table summarizes the "algebraic" overlay policy. diff --git a/docs/coulomb-runtime.md b/docs/coulomb-runtime.md index 3c5a28e22..bf218a5d1 100644 --- a/docs/coulomb-runtime.md +++ b/docs/coulomb-runtime.md @@ -29,11 +29,6 @@ import coulomb.syntax.* // algebraic definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit and value type policies for operations -import coulomb.policy.standard.given -import scala.language.implicitConversions // unit definitions import coulomb.units.si.{*, given} @@ -42,6 +37,7 @@ import coulomb.units.info.{*, given} import coulomb.units.time.{*, given} // runtime definitions +import coulomb.runtime.syntax.* import coulomb.conversion.runtimes.mapping.MappingCoefficientRuntime ``` diff --git a/docs/coulomb-spire.md b/docs/coulomb-spire.md deleted file mode 100644 index 2db23e890..000000000 --- a/docs/coulomb-spire.md +++ /dev/null @@ -1,134 +0,0 @@ -# coulomb-spire - -The `coulomb-spire` package defines unit conversion, value conversion, -and value resolution -[policies][policy-concepts] -for -[spire](https://typelevel.org/spire/) -numeric types (and standard Scala numeric types). - -The following numeric types are supported: - -| Value Type | Defined In | -| --- | --- | -| Int | Scala | -| Long | Scala | -| Float | Scala | -| Double | Scala | -| BigInt | Scala | -| BigDecimal | Scala | -| Rational | Spire | -| Algebraic | Spire | -| Real | Spire | - -@:callout(info) -You may notice that `BigInt` and `BigDecimal` are not supported in `coulomb-core`, -even though they are Scala native types. -This is because Scala's native numeric typeclasses do not uniformly treat the -core types `Int, Long, Float, Double` the same as `BigInt` and `BigDecimal`, -while spire's typeclasses do. -For this reason, it is much easier to support `BigInt` and `BigDecimal` as part of -the `coulomb-spire` package. -@:@ - -## Quick Start - -### documentation - -You can browse the `coulomb-spire` policies -[here](https://www.javadoc.io/doc/com.manyangled/coulomb-docs_3/latest/coulomb/policy/spire.html). - -### packages - -Include `coulomb-spire` with your Scala project: - -```scala -libraryDependencies += "com.manyangled" %% "coulomb-core" % "@VERSION@" -libraryDependencies += "com.manyangled" %% "coulomb-spire" % "@VERSION@" -``` - -@:callout(info) -To use coulomb unit definitions: -```scala -libraryDependencies += "com.manyangled" %% "coulomb-units" % "@VERSION@" -``` -@:@ - -### import - -To import the standard (non-strict) spire policy: - -```scala mdoc -import spire.math.* - -// fundamental coulomb types and methods -import coulomb.* -import coulomb.syntax.* - -// algebraic definitions -import algebra.instances.all.given -import coulomb.ops.algebra.spire.all.{*, given} - -// standard policy for spire and scala types -import coulomb.policy.spire.standard.given -import scala.language.implicitConversions -``` - -@:callout(info) -Never import more than one `policy` at a time. -For example, if you import `coulomb.policy.spire.standard.given`, -do not also import `coulomb.policy.standard.given.` -@:@ - -### examples - -```scala mdoc -import coulomb.units.si.{*, given} -import coulomb.units.us.{*, given} - -// coulomb-spire policies allow the use of spire and Scala types -val rq = Rational(3, 2).withUnit[Meter] -val bq = BigDecimal(1).withUnit[Yard] -val iq = 1.withUnit[Meter] - -// The standard policy supports implicit conversions of unit and value types -rq + bq + iq -``` - -## Policies - -As with `coulomb-core`, the `coulomb-spire` package provides two predefined -[policy][policy-concepts] -options: - -- `coulomb.policy.spire.standard` - Supports implicit and explicit value and unit conversions, and value promotions for spire and Scala numeric types. -- `coulomb.policy.spire.strict` - Only explicit value and unit conversions are supported. - -The -[value resolution][value-resolution-concepts] -and promotion rules for `coulomb-spire` are extended to -include `BigDecimal`, `BigInt`, `Rational`, `Algebraic` and `Real`. -The resulting lattice of promotions looks like this: - -| Promote From | To | -| --- | --- | -| Int | Long | -| Long | BigInt | -| BigInt | Float | -| Long | Float | -| Float | Double | -| Double | BigDecimal | -| BigDecimal | Rational | -| Rational | Algebraic | -| Algebraic | Real | - -@:callout(info) -Remember that the promotions above are transitive, -and so `Int` promotes to `Real`, etc. -@:@ - -The definition of promotions for `coulomb-spire` can be browsed -[here](https://www.javadoc.io/doc/com.manyangled/coulomb-docs_3/latest/coulomb/ops/resolution/spire$.html) - -[value-resolution-concepts]: coulomb-core.md#value-promotion-and-resolution -[policy-concepts]: coulomb-core.md#coulomb-policies diff --git a/docs/coulomb-units.md b/docs/coulomb-units.md index 646a4082a..42937d3fe 100644 --- a/docs/coulomb-units.md +++ b/docs/coulomb-units.md @@ -26,11 +26,6 @@ import coulomb.syntax.* // algebraic definitions import algebra.instances.all.given -import coulomb.ops.algebra.all.given - -// unit and value type policies for operations -import coulomb.policy.standard.given -import scala.language.implicitConversions ``` ### documentation @@ -126,26 +121,21 @@ In `coulomb-units`, standard `Quantity` of time units such as `Second`, `Minute` corresponds to `Duration` in `java.time`. Similarly, absolute time instants represented by `EpochTime` correspond to `Instant` in `java.time`. -The `coulomb-units` package implements both explicit and implicit conversions between +The `coulomb-units` package implements conversion methods between `coulomb` and `java.time` values, some of which are shown here: ```scala mdoc import java.time.{ Duration, Instant } import coulomb.units.time.{*, given} -// explicit conversion methods +// extension conversion methods import coulomb.units.javatime.* -// implicit and explicit conversions -import coulomb.units.javatime.conversions.all.given val dur = Duration.ofSeconds(70, 400000000) // explicit conversion from java.time duration to a coulomb quantity dur.toQuantity[Double, Minute] -// corresponding implicit conversion -val dq: Quantity[Double, Minute] = dur - // convert back to java.time dq.toDuration @@ -155,9 +145,19 @@ val ins = Instant.parse("1969-07-20T00:00:00Z") // days relative to standard Unix epoch ins.toEpochTime[Double, Day] -// corresponding implicit conversion -val et: EpochTime[Double, Day] = ins - // convert back to java.time et.toInstant ``` + +Implicit conversions can also be imported: + +```scala mdoc +// implicit java.time conversions +import coulomb.units.javatime.conversion.implicits.given +import scala.language.implicitConversions + +// implicit conversions +val dq: Quantity[Double, Minute] = dur + +val et: EpochTime[Double, Day] = ins +``` diff --git a/docs/develop.md b/docs/develop.md index d12080f87..b9ce5b410 100644 --- a/docs/develop.md +++ b/docs/develop.md @@ -53,9 +53,7 @@ scala> import coulomb.* | import coulomb.syntax.* | | import algebra.instances.all.given - | import coulomb.ops.algebra.spire.all.given | - | import coulomb.policy.spire.standard.given | import coulomb.units.si.* | import coulomb.units.si.given