From a795b93c08cc4de4b8e43f8c56649e5cdd78cfbd Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Thu, 31 Mar 2022 11:39:37 -0700 Subject: [PATCH 01/35] PowImplFP experiment --- core/src/main/scala/coulomb/ops/standard/pow.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/main/scala/coulomb/ops/standard/pow.scala b/core/src/main/scala/coulomb/ops/standard/pow.scala index 1e24d43ba..bd68114d7 100644 --- a/core/src/main/scala/coulomb/ops/standard/pow.scala +++ b/core/src/main/scala/coulomb/ops/standard/pow.scala @@ -26,16 +26,25 @@ import coulomb.ops.{Pow, SimplifiedUnit} import coulomb.rational.typeexpr import coulomb.ops.algebra.FractionalPower +class PowImplFP[V, U, E, UOp](alg: FractionalPower[V], e: Double) extends Pow[V, U, E]: + type VO = V + type UO = UOp + def apply(q: Quantity[V, U]): Quantity[VO, UO] = + alg.pow(q.value, e).withUnit[UO] + transparent inline given ctx_pow_FractionalPower[V, U, E](using alg: FractionalPower[V], su: SimplifiedUnit[U ^ E] ): Pow[V, U, E] = + new PowImplFP[V, U, E, su.UO](alg, typeexpr.double[E]) + /* val e = typeexpr.double[E] new Pow[V, U, E]: type VO = V type UO = su.UO def apply(q: Quantity[V, U]): Quantity[VO, UO] = alg.pow(q.value, e).withUnit[UO] + */ transparent inline given ctx_pow_MultiplicativeGroup[V, U, E](using nfp: NotGiven[FractionalPower[V]], From a933042cb16fe90126ad6057ec637038a59c1b79 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Thu, 31 Mar 2022 17:44:20 -0700 Subject: [PATCH 02/35] study1 and study2 --- core/src/main/scala/coulomb/ops/standard/pow.scala | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/src/main/scala/coulomb/ops/standard/pow.scala b/core/src/main/scala/coulomb/ops/standard/pow.scala index bd68114d7..2183a9dd3 100644 --- a/core/src/main/scala/coulomb/ops/standard/pow.scala +++ b/core/src/main/scala/coulomb/ops/standard/pow.scala @@ -26,6 +26,19 @@ import coulomb.ops.{Pow, SimplifiedUnit} import coulomb.rational.typeexpr import coulomb.ops.algebra.FractionalPower +object study1: + import coulomb.*, algebra.instances.all.given, coulomb.ops.standard.given, coulomb.policy.standard.given + val x = 2d.withUnit[String] + val y = 2f.withUnit[Int] + val z = 2f.withUnit[Boolean] + +object study2: + import coulomb.*, algebra.instances.all.given, coulomb.ops.standard.given, coulomb.policy.standard.given + import coulomb.ops.standard.study1.* + val a = x.pow[2] + val b = y.pow[3] + val c = z.pow[4] + class PowImplFP[V, U, E, UOp](alg: FractionalPower[V], e: Double) extends Pow[V, U, E]: type VO = V type UO = UOp From b6a9de20195e368b5df30a8ec3d0e28691a2dbd4 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Fri, 1 Apr 2022 13:34:34 -0700 Subject: [PATCH 03/35] pow --- .../main/scala/coulomb/ops/standard/all.scala | 21 +++++ .../main/scala/coulomb/ops/standard/pow.scala | 91 ++++++++----------- 2 files changed, 58 insertions(+), 54 deletions(-) create mode 100644 core/src/main/scala/coulomb/ops/standard/all.scala diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala new file mode 100644 index 000000000..987cb3e60 --- /dev/null +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -0,0 +1,21 @@ +/* + * Copyright 2022 Erik Erlandson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package coulomb.ops.standard + +// eventually these go in `object all` +export pow.given + diff --git a/core/src/main/scala/coulomb/ops/standard/pow.scala b/core/src/main/scala/coulomb/ops/standard/pow.scala index 2183a9dd3..07e5f00c4 100644 --- a/core/src/main/scala/coulomb/ops/standard/pow.scala +++ b/core/src/main/scala/coulomb/ops/standard/pow.scala @@ -26,62 +26,45 @@ import coulomb.ops.{Pow, SimplifiedUnit} import coulomb.rational.typeexpr import coulomb.ops.algebra.FractionalPower -object study1: - import coulomb.*, algebra.instances.all.given, coulomb.ops.standard.given, coulomb.policy.standard.given - val x = 2d.withUnit[String] - val y = 2f.withUnit[Int] - val z = 2f.withUnit[Boolean] +object pow: + transparent inline given ctx_pow_FractionalPower[V, U, E](using + alg: FractionalPower[V], + su: SimplifiedUnit[U ^ E] + ): Pow[V, U, E] = + new infra.PowFP[V, U, E, su.UO](alg, typeexpr.double[E]) -object study2: - import coulomb.*, algebra.instances.all.given, coulomb.ops.standard.given, coulomb.policy.standard.given - import coulomb.ops.standard.study1.* - val a = x.pow[2] - val b = y.pow[3] - val c = z.pow[4] + transparent inline given ctx_pow_MultiplicativeGroup[V, U, E](using + nfp: NotGiven[FractionalPower[V]], + alg: MultiplicativeGroup[V], + aie: typeexpr.AllInt[E], + su: SimplifiedUnit[U ^ E] + ): Pow[V, U, E] = + new infra.PowMG[V, U, E, su.UO](alg, aie.value) -class PowImplFP[V, U, E, UOp](alg: FractionalPower[V], e: Double) extends Pow[V, U, E]: - type VO = V - type UO = UOp - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] + transparent inline given ctx_pow_MultiplicativeSemigroup[V, U, E](using + nfp: NotGiven[FractionalPower[V]], + nmg: NotGiven[MultiplicativeGroup[V]], + alg: MultiplicativeSemigroup[V], + pie: typeexpr.PosInt[E], + su: SimplifiedUnit[U ^ E] + ): Pow[V, U, E] = + new infra.PowMSG[V, U, E, su.UO](alg, pie.value) -transparent inline given ctx_pow_FractionalPower[V, U, E](using - alg: FractionalPower[V], - su: SimplifiedUnit[U ^ E] - ): Pow[V, U, E] = - new PowImplFP[V, U, E, su.UO](alg, typeexpr.double[E]) - /* - val e = typeexpr.double[E] - new Pow[V, U, E]: - type VO = V - type UO = su.UO - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] - */ + object infra: + class PowFP[V, U, E, UOp](alg: FractionalPower[V], e: Double) extends Pow[V, U, E]: + type VO = V + type UO = UOp + def apply(q: Quantity[V, U]): Quantity[VO, UO] = + alg.pow(q.value, e).withUnit[UO] -transparent inline given ctx_pow_MultiplicativeGroup[V, U, E](using - nfp: NotGiven[FractionalPower[V]], - alg: MultiplicativeGroup[V], - aie: typeexpr.AllInt[E], - su: SimplifiedUnit[U ^ E] - ): Pow[V, U, E] = - val e = aie.value - new Pow[V, U, E]: - type VO = V - type UO = su.UO - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] + class PowMG[V, U, E, UOp](alg: MultiplicativeGroup[V], e: Int) extends Pow[V, U, E]: + type VO = V + type UO = UOp + def apply(q: Quantity[V, U]): Quantity[VO, UO] = + alg.pow(q.value, e).withUnit[UO] -transparent inline given ctx_pow_MultiplicativeSemigroup[V, U, E](using - nfp: NotGiven[FractionalPower[V]], - nmg: NotGiven[MultiplicativeGroup[V]], - alg: MultiplicativeSemigroup[V], - pie: typeexpr.PosInt[E], - su: SimplifiedUnit[U ^ E] - ): Pow[V, U, E] = - val e = pie.value - new Pow[V, U, E]: - type VO = V - type UO = su.UO - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] + class PowMSG[V, U, E, UOp](alg: MultiplicativeSemigroup[V], e: Int) extends Pow[V, U, E]: + type VO = V + type UO = UOp + def apply(q: Quantity[V, U]): Quantity[VO, UO] = + alg.pow(q.value, e).withUnit[UO] From 57324c9f8f4e14975521bea866de9907597264ae Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 06:41:21 -0700 Subject: [PATCH 04/35] implicit conversions --- .../coulomb/conversion/standard/scala.scala | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/core/src/main/scala/coulomb/conversion/standard/scala.scala b/core/src/main/scala/coulomb/conversion/standard/scala.scala index 4e7c05886..c7c0ae822 100644 --- a/core/src/main/scala/coulomb/conversion/standard/scala.scala +++ b/core/src/main/scala/coulomb/conversion/standard/scala.scala @@ -26,35 +26,54 @@ object scala: // https://docs.scala-lang.org/scala3/reference/contextual/conversions.html given ctx_Quantity_Conversion_1V1U[V, U]: Conversion[Quantity[V, U], Quantity[V, U]] = - new Conversion[Quantity[V, U], Quantity[V, U]]: - def apply(q: Quantity[V, U]): Quantity[V, U] = q + new infra.QC1V1U[V, U] given ctx_Quantity_Conversion_1V2U[V, UF, UT](using uc: UnitConversion[V, UF, UT] ): Conversion[Quantity[V, UF], Quantity[V, UT]] = - new Conversion[Quantity[V, UF], Quantity[V, UT]]: - def apply(q: Quantity[V, UF]): Quantity[V, UT] = - uc(q.value).withUnit[UT] + new infra.QC1V2U[V, UF, UT](uc) given ctx_Quantity_Conversion_2V1U[U, VF, VT](using vc: ValueConversion[VF, VT], ): Conversion[Quantity[VF, U], Quantity[VT, U]] = - new Conversion[Quantity[VF, U], Quantity[VT, U]]: - def apply(q: Quantity[VF, U]): Quantity[VT, U] = - vc(q.value).withUnit[U] + new infra.QC2V1U[U, VF, VT](vc) given ctx_Quantity_Conversion_2V2U[VF, UF, VT, UT](using vc: ValueConversion[VF, VT], uc: UnitConversion[VT, UF, UT] ): Conversion[Quantity[VF, UF], Quantity[VT, UT]] = - new Conversion[Quantity[VF, UF], Quantity[VT, UT]]: - def apply(q: Quantity[VF, UF]): Quantity[VT, UT] = - uc(vc(q.value)).withUnit[UT] + new infra.QC2V2U[VF, UF, VT, UT](vc, uc) given ctx_DeltaQuantity_conversion_2V2U[B, VF, UF, VT, UT](using vc: ValueConversion[VF, VT], uc: DeltaUnitConversion[VT, B, UF, UT] ): Conversion[DeltaQuantity[VF, UF, B], DeltaQuantity[VT, UT, B]] = - new Conversion[DeltaQuantity[VF, UF, B], DeltaQuantity[VT, UT, B]]: + new infra.DQC2V2U[B, VF, UF, VT, UT](vc, uc) + + object infra: + class QC1V1U[V, U] extends Conversion[Quantity[V, U], Quantity[V, U]]: + def apply(q: Quantity[V, U]): Quantity[V, U] = q + + class QC1V2U[V, UF, UT](uc: UnitConversion[V, UF, UT]) extends + Conversion[Quantity[V, UF], Quantity[V, UT]]: + def apply(q: Quantity[V, UF]): Quantity[V, UT] = + uc(q.value).withUnit[UT] + + class QC2V1U[U, VF, VT](vc: ValueConversion[VF, VT]) extends + Conversion[Quantity[VF, U], Quantity[VT, U]]: + def apply(q: Quantity[VF, U]): Quantity[VT, U] = + vc(q.value).withUnit[U] + + class QC2V2U[VF, UF, VT, UT]( + vc: ValueConversion[VF, VT], + uc: UnitConversion[VT, UF, UT]) extends + Conversion[Quantity[VF, UF], Quantity[VT, UT]]: + def apply(q: Quantity[VF, UF]): Quantity[VT, UT] = + uc(vc(q.value)).withUnit[UT] + + class DQC2V2U[B, VF, UF, VT, UT]( + vc: ValueConversion[VF, VT], + uc: DeltaUnitConversion[VT, B, UF, UT]) extends + Conversion[DeltaQuantity[VF, UF, B], DeltaQuantity[VT, UT, B]]: def apply(q: DeltaQuantity[VF, UF, B]): DeltaQuantity[VT, UT, B] = uc(vc(q.value)).withDeltaUnit[UT, B] From 7c0c5680e541ca74c1aa835ddac8b2c5ac4c3ffb Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 07:30:06 -0700 Subject: [PATCH 05/35] named unit conversion classes --- .../coulomb/conversion/standard/unit.scala | 88 ++++++++++--------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/core/src/main/scala/coulomb/conversion/standard/unit.scala b/core/src/main/scala/coulomb/conversion/standard/unit.scala index ef1e08d6d..1434fb540 100644 --- a/core/src/main/scala/coulomb/conversion/standard/unit.scala +++ b/core/src/main/scala/coulomb/conversion/standard/unit.scala @@ -22,61 +22,67 @@ object unit: import coulomb.rational.Rational inline given ctx_UC_Rational[UF, UT]: UnitConversion[Rational, UF, UT] = - val c = coefficientRational[UF, UT] - new UnitConversion[Rational, UF, UT]: - def apply(v: Rational): Rational = c * v + new infra.RationalUC[UF, UT](coefficientRational[UF, UT]) inline given ctx_UC_Double[UF, UT]: UnitConversion[Double, UF, UT] = - val c = coefficientDouble[UF, UT] - new UnitConversion[Double, UF, UT]: - def apply(v: Double): Double = c * v + new infra.DoubleUC[UF, UT](coefficientDouble[UF, UT]) inline given ctx_UC_Float[UF, UT]: UnitConversion[Float, UF, UT] = - val c = coefficientFloat[UF, UT] - new UnitConversion[Float, UF, UT]: - def apply(v: Float): Float = c * v + new infra.FloatUC[UF, UT](coefficientFloat[UF, UT]) inline given ctx_TUC_Long[UF, UT]: TruncatingUnitConversion[Long, UF, UT] = - val nc = coefficientNumDouble[UF, UT] - val dc = coefficientDenDouble[UF, UT] - // using nc and dc is more efficient than using Rational directly in the conversion function - // but still gives us 53 bits of integer precision for exact rational arithmetic, and also - // graceful loss of precision if nc*v exceeds 53 bits - new TruncatingUnitConversion[Long, UF, UT]: - def apply(v: Long): Long = ((nc * v) / dc).toLong + new infra.LongTUC[UF, UT](coefficientNumDouble[UF, UT], coefficientDenDouble[UF, UT]) inline given ctx_TUC_Int[UF, UT]: TruncatingUnitConversion[Int, UF, UT] = - val nc = coefficientNumDouble[UF, UT] - val dc = coefficientDenDouble[UF, UT] - new TruncatingUnitConversion[Int, UF, UT]: - def apply(v: Int): Int = ((nc * v) / dc).toInt + new infra.IntTUC[UF, UT](coefficientNumDouble[UF, UT], coefficientDenDouble[UF, UT]) inline given ctx_DUC_Double[B, UF, UT]: DeltaUnitConversion[Double, B, UF, UT] = - val c = coefficientDouble[UF, UT] - val df = deltaOffsetDouble[UF, B] - val dt = deltaOffsetDouble[UT, B] - new DeltaUnitConversion[Double, B, UF, UT]: - def apply(v: Double): Double = ((v + df) * c) - dt + new infra.DoubleDUC[B, UF, UT]( + coefficientDouble[UF, UT], deltaOffsetDouble[UF, B], deltaOffsetDouble[UT, B]) inline given ctx_DUC_Float[B, UF, UT]: DeltaUnitConversion[Float, B, UF, UT] = - val c = coefficientFloat[UF, UT] - val df = deltaOffsetFloat[UF, B] - val dt = deltaOffsetFloat[UT, B] - new DeltaUnitConversion[Float, B, UF, UT]: - def apply(v: Float): Float = ((v + df) * c) - dt + new infra.FloatDUC[B, UF, UT]( + coefficientFloat[UF, UT], deltaOffsetFloat[UF, B], deltaOffsetFloat[UT, B]) inline given ctx_TDUC_Long[B, UF, UT]: TruncatingDeltaUnitConversion[Long, B, UF, UT] = - val nc = coefficientNumDouble[UF, UT] - val dc = coefficientDenDouble[UF, UT] - val df = deltaOffsetDouble[UF, B] - val dt = deltaOffsetDouble[UT, B] - new TruncatingDeltaUnitConversion[Long, B, UF, UT]: - def apply(v: Long): Long = (((nc * (v + df)) / dc) - dt).toLong + new infra.LongTDUC[B, UF, UT]( + coefficientNumDouble[UF, UT], coefficientDenDouble[UF, UT], + deltaOffsetDouble[UF, B], deltaOffsetDouble[UT, B]) inline given ctx_TDUC_Int[B, UF, UT]: TruncatingDeltaUnitConversion[Int, B, UF, UT] = - val nc = coefficientNumDouble[UF, UT] - val dc = coefficientDenDouble[UF, UT] - val df = deltaOffsetDouble[UF, B] - val dt = deltaOffsetDouble[UT, B] - new TruncatingDeltaUnitConversion[Int, B, UF, UT]: + new infra.IntTDUC[B, UF, UT]( + coefficientNumDouble[UF, UT], coefficientDenDouble[UF, UT], + deltaOffsetDouble[UF, B], deltaOffsetDouble[UT, B]) + + object infra: + class RationalUC[UF, UT](c: Rational) extends UnitConversion[Rational, UF, UT]: + def apply(v: Rational): Rational = c * v + + class DoubleUC[UF, UT](c: Double) extends UnitConversion[Double, UF, UT]: + def apply(v: Double): Double = c * v + + class FloatUC[UF, UT](c: Float) extends UnitConversion[Float, UF, UT]: + def apply(v: Float): Float = c * v + + class LongTUC[UF, UT](nc: Double, dc: Double) extends TruncatingUnitConversion[Long, UF, UT]: + // using nc and dc is more efficient than using Rational directly in the conversion function + // but still gives us 53 bits of integer precision for exact rational arithmetic, and also + // graceful loss of precision if nc*v exceeds 53 bits + def apply(v: Long): Long = ((nc * v) / dc).toLong + + class IntTUC[UF, UT](nc: Double, dc: Double) extends TruncatingUnitConversion[Int, UF, UT]: + def apply(v: Int): Int = ((nc * v) / dc).toInt + + class DoubleDUC[B, UF, UT](c: Double, df: Double, dt: Double) extends DeltaUnitConversion[Double, B, UF, UT]: + def apply(v: Double): Double = ((v + df) * c) - dt + + class FloatDUC[B, UF, UT](c: Float, df: Float, dt: Float) extends DeltaUnitConversion[Float, B, UF, UT]: + def apply(v: Float): Float = ((v + df) * c) - dt + + class LongTDUC[B, UF, UT](nc: Double, dc: Double, df: Double, dt: Double) extends + TruncatingDeltaUnitConversion[Long, B, UF, UT]: + def apply(v: Long): Long = (((nc * (v + df)) / dc) - dt).toLong + + class IntTDUC[B, UF, UT](nc: Double, dc: Double, df: Double, dt: Double) extends + TruncatingDeltaUnitConversion[Int, B, UF, UT]: def apply(v: Int): Int = (((nc * (v + df)) / dc) - dt).toInt From 8106a6c22c13fe1f3fabcb59790d276743623578 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 08:12:42 -0700 Subject: [PATCH 06/35] named simplify class --- core/src/main/scala/coulomb/infra/meta.scala | 5 --- core/src/main/scala/coulomb/ops/ops.scala | 4 --- .../main/scala/coulomb/ops/standard/all.scala | 2 +- .../scala/coulomb/ops/standard/simplify.scala | 34 +++++++++++++++++++ 4 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 core/src/main/scala/coulomb/ops/standard/simplify.scala diff --git a/core/src/main/scala/coulomb/infra/meta.scala b/core/src/main/scala/coulomb/infra/meta.scala index 510377d81..facb6778a 100644 --- a/core/src/main/scala/coulomb/infra/meta.scala +++ b/core/src/main/scala/coulomb/infra/meta.scala @@ -233,11 +233,6 @@ object meta: val (nsig, dsig) = sortsig(tail) if (e > 0) ((u, e) :: nsig, dsig) else (nsig, (u, -e) :: dsig) - def simplifiedUnit[U](using Quotes, Type[U]): Expr[SimplifiedUnit[U]] = - import quotes.reflect.* - simplify(TypeRepr.of[U]).asType match - case '[uo] => '{ new SimplifiedUnit[U] { type UO = uo } } - def simplify(using Quotes)(u: quotes.reflect.TypeRepr): quotes.reflect.TypeRepr = import quotes.reflect.* val (un, ud) = sortsig(stdsig(u)) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index d7f4bd821..a6109914d 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -100,7 +100,3 @@ abstract class ValueResolution[VL, VR]: @implicitNotFound("Unable to simplify unit type ${U}") abstract class SimplifiedUnit[U]: type UO - -object SimplifiedUnit: - transparent inline given ctx_SimplifiedUnit[U]: SimplifiedUnit[U] = - ${ coulomb.infra.meta.simplifiedUnit[U] } diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index 987cb3e60..1acc38612 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -18,4 +18,4 @@ package coulomb.ops.standard // eventually these go in `object all` export pow.given - +export simplify.given diff --git a/core/src/main/scala/coulomb/ops/standard/simplify.scala b/core/src/main/scala/coulomb/ops/standard/simplify.scala new file mode 100644 index 000000000..ec6d6bef8 --- /dev/null +++ b/core/src/main/scala/coulomb/ops/standard/simplify.scala @@ -0,0 +1,34 @@ +/* + * Copyright 2022 Erik Erlandson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package coulomb.ops.standard + +object simplify: + import coulomb.ops.SimplifiedUnit + + transparent inline given ctx_SimplifiedUnit[U]: SimplifiedUnit[U] = + ${ infra.simplifiedUnit[U] } + + object infra: + import scala.quoted.* + + class SU[U, UOp] extends SimplifiedUnit[U]: + type UO = UOp + + def simplifiedUnit[U](using Quotes, Type[U]): Expr[SimplifiedUnit[U]] = + import quotes.reflect.* + coulomb.infra.meta.simplify(TypeRepr.of[U]).asType match + case '[uo] => '{ new SU[U, uo] } From 833338b0cf8641e233b5c1e32b2669ba08fb640c Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 08:39:52 -0700 Subject: [PATCH 07/35] unused import --- core/src/main/scala/coulomb/infra/meta.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/scala/coulomb/infra/meta.scala b/core/src/main/scala/coulomb/infra/meta.scala index facb6778a..3154642c8 100644 --- a/core/src/main/scala/coulomb/infra/meta.scala +++ b/core/src/main/scala/coulomb/infra/meta.scala @@ -19,7 +19,6 @@ package coulomb.infra import coulomb.rational.Rational import coulomb.* import coulomb.define.* -import coulomb.ops.* object meta: import scala.quoted.* From 4a436e9cb3040f55c8a50b78aec09814989e253f Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 09:28:47 -0700 Subject: [PATCH 08/35] named add --- .../main/scala/coulomb/ops/standard/add.scala | 118 ++++++++++-------- .../main/scala/coulomb/ops/standard/all.scala | 1 + 2 files changed, 66 insertions(+), 53 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/add.scala b/core/src/main/scala/coulomb/ops/standard/add.scala index a61244dfb..ebeccc85f 100644 --- a/core/src/main/scala/coulomb/ops/standard/add.scala +++ b/core/src/main/scala/coulomb/ops/standard/add.scala @@ -16,62 +16,74 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object add: + import scala.util.NotGiven + import scala.Conversion -import algebra.ring.AdditiveSemigroup + import algebra.ring.AdditiveSemigroup -import coulomb.{Quantity, withUnit} -import coulomb.ops.{Add, ValueResolution} + import coulomb.{Quantity, withUnit} + import coulomb.ops.{Add, ValueResolution} -transparent inline given ctx_add_1V1U[VL, UL, VR, UR](using - // https://github.com/lampepfl/dotty/issues/14585 - eqv: VR =:= VL, - equ: UR =:= UL, - alg: AdditiveSemigroup[VL] - ): Add[VL, UL, VR, UR] = - new Add[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(ql.value, eqv(qr.value)).withUnit[UO] + transparent inline given ctx_add_1V1U[VL, UL, VR, UR](using + // https://github.com/lampepfl/dotty/issues/14585 + eqv: VR =:= VL, + equ: UR =:= UL, + alg: AdditiveSemigroup[VL] + ): Add[VL, UL, VR, UR] = + new infra.Add1V1U[VL, UL, VR, UR](alg, eqv) -transparent inline given ctx_add_1V2U[VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], - alg: AdditiveSemigroup[VL] - ): Add[VL, UL, VR, UR] = - new Add[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(ql.value, icr(qr).value).withUnit[UO] + transparent inline given ctx_add_1V2U[VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], + alg: AdditiveSemigroup[VL] + ): Add[VL, UL, VR, UR] = + new infra.Add1V2U[VL, UL, VR, UR](alg, icr) -transparent inline given ctx_add_2V1U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - 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 Add[VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(icl(ql).value, icr(qr).value).withUnit[UO] + transparent inline given ctx_add_2V1U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + 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.Add2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + + transparent inline given ctx_add_2V2U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + 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.Add2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + + object infra: + class Add1V1U[VL, UL, VR, UR]( + alg: AdditiveSemigroup[VL], + eqv: VR =:= VL) extends Add[VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.plus(ql.value, eqv(qr.value)).withUnit[UO] + + class Add1V2U[VL, UL, VR, UR]( + alg: AdditiveSemigroup[VL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends Add[VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.plus(ql.value, icr(qr).value).withUnit[UO] + + class Add2V2U[VL, UL, VR, UR, VOp]( + alg: AdditiveSemigroup[VOp], + icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends Add[VL, UL, VR, UR]: + type VO = VOp + type UO = UL + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.plus(icl(ql).value, icr(qr).value).withUnit[UO] -transparent inline given ctx_add_2V2U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - 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 Add[VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(icl(ql).value, icr(qr).value).withUnit[UO] diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index 1acc38612..95b874d38 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -17,5 +17,6 @@ package coulomb.ops.standard // eventually these go in `object all` +export add.given export pow.given export simplify.given From 721ee813de90b26c82a440021bff5978411156f8 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 10:44:53 -0700 Subject: [PATCH 09/35] named sub --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../main/scala/coulomb/ops/standard/sub.scala | 118 ++++++++++-------- 2 files changed, 66 insertions(+), 53 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index 95b874d38..d23d0954a 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -18,5 +18,6 @@ package coulomb.ops.standard // eventually these go in `object all` export add.given +export sub.given export pow.given export simplify.given diff --git a/core/src/main/scala/coulomb/ops/standard/sub.scala b/core/src/main/scala/coulomb/ops/standard/sub.scala index a8b5d3232..8acfb25db 100644 --- a/core/src/main/scala/coulomb/ops/standard/sub.scala +++ b/core/src/main/scala/coulomb/ops/standard/sub.scala @@ -16,62 +16,74 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object sub: + import scala.util.NotGiven + import scala.Conversion -import algebra.ring.AdditiveGroup + import algebra.ring.AdditiveGroup -import coulomb.{Quantity, withUnit} -import coulomb.ops.{Sub, ValueResolution} + import coulomb.{Quantity, withUnit} + import coulomb.ops.{Sub, ValueResolution} -transparent inline given ctx_sub_1V1U[VL, UL, VR, UR](using - // https://github.com/lampepfl/dotty/issues/14585 - eqv: VR =:= VL, - equ: UR =:= UL, - alg: AdditiveGroup[VL] - ): Sub[VL, UL, VR, UR] = - new Sub[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(ql.value, eqv(qr.value)).withUnit[UO] + transparent inline given ctx_sub_1V1U[VL, UL, VR, UR](using + // https://github.com/lampepfl/dotty/issues/14585 + eqv: VR =:= VL, + equ: UR =:= UL, + alg: AdditiveGroup[VL] + ): Sub[VL, UL, VR, UR] = + new infra.Sub1V1U[VL, UL, VR, UR](alg, eqv) -transparent inline given ctx_sub_1V2U[VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], - alg: AdditiveGroup[VL] - ): Sub[VL, UL, VR, UR] = - new Sub[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(ql.value, icr(qr).value).withUnit[UO] + transparent inline given ctx_sub_1V2U[VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], + alg: AdditiveGroup[VL] + ): Sub[VL, UL, VR, UR] = + new infra.Sub1V2U[VL, UL, VR, UR](alg, icr) -transparent inline given ctx_sub_2V1U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveGroup[vres.VO] - ): Sub[VL, UL, VR, UR] = - new Sub[VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] + transparent inline given ctx_sub_2V1U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + alg: AdditiveGroup[vres.VO] + ): Sub[VL, UL, VR, UR] = + new infra.Sub2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + + transparent inline given ctx_sub_2V2U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + alg: AdditiveGroup[vres.VO] + ): Sub[VL, UL, VR, UR] = + new infra.Sub2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + + object infra: + class Sub1V1U[VL, UL, VR, UR]( + alg: AdditiveGroup[VL], + eqv: VR =:= VL) extends Sub[VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.minus(ql.value, eqv(qr.value)).withUnit[UO] + + class Sub1V2U[VL, UL, VR, UR]( + alg: AdditiveGroup[VL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends Sub[VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.minus(ql.value, icr(qr).value).withUnit[UO] + + class Sub2V2U[VL, UL, VR, UR, VOp]( + alg: AdditiveGroup[VOp], + icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends Sub[VL, UL, VR, UR]: + type VO = VOp + type UO = UL + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] -transparent inline given ctx_sub_2V2U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveGroup[vres.VO] - ): Sub[VL, UL, VR, UR] = - new Sub[VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] From 6f7b5dbcb81de62ecf3a3696c0b2a1cb86072962 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 11:09:52 -0700 Subject: [PATCH 10/35] named mul --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../main/scala/coulomb/ops/standard/mul.scala | 78 +++++++++++-------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index d23d0954a..e284629a3 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -19,5 +19,6 @@ package coulomb.ops.standard // eventually these go in `object all` export add.given export sub.given +export mul.given export pow.given export simplify.given diff --git a/core/src/main/scala/coulomb/ops/standard/mul.scala b/core/src/main/scala/coulomb/ops/standard/mul.scala index fb73ec663..15ad7b244 100644 --- a/core/src/main/scala/coulomb/ops/standard/mul.scala +++ b/core/src/main/scala/coulomb/ops/standard/mul.scala @@ -16,36 +16,48 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion - -import algebra.ring.MultiplicativeSemigroup - -import coulomb.{`*`, Quantity, withUnit} -import coulomb.ops.{Mul, SimplifiedUnit, ValueResolution} - -transparent inline given ctx_mul_1V2U[VL, UL, VR, UR](using - // https://github.com/lampepfl/dotty/issues/14585 - eqv: VR =:= VL, - alg: MultiplicativeSemigroup[VL], - su: SimplifiedUnit[UL * UR] - ): Mul[VL, UL, VR, UR] = - new Mul[VL, UL, VR, UR]: - type VO = VL - type UO = su.UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.times(ql.value, eqv(qr.value)).withUnit[UO] - -transparent inline given ctx_mul_2V2U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UR]], - alg: MultiplicativeSemigroup[vres.VO], - su: SimplifiedUnit[UL * UR] - ): Mul[VL, UL, VR, UR] = - new Mul[VL, UL, VR, UR]: - type VO = vres.VO - type UO = su.UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.times(icl(ql).value, icr(qr).value).withUnit[UO] +object mul: + import scala.util.NotGiven + import scala.Conversion + + import algebra.ring.MultiplicativeSemigroup + + import coulomb.{`*`, Quantity, withUnit} + import coulomb.ops.{Mul, SimplifiedUnit, ValueResolution} + + transparent inline given ctx_mul_1V2U[VL, UL, VR, UR](using + // https://github.com/lampepfl/dotty/issues/14585 + eqv: VR =:= VL, + alg: MultiplicativeSemigroup[VL], + su: SimplifiedUnit[UL * UR] + ): Mul[VL, UL, VR, UR] = + new infra.Mul1V2U[VL, UL, VR, UR, su.UO](alg, eqv) + + transparent inline given ctx_mul_2V2U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UR]], + alg: MultiplicativeSemigroup[vres.VO], + su: SimplifiedUnit[UL * UR] + ): Mul[VL, UL, VR, UR] = + new infra.Mul2V2U[VL, UL, VR, UR, vres.VO, su.UO](alg, icl, icr) + + object infra: + class Mul1V2U[VL, UL, VR, UR, UOp]( + alg: MultiplicativeSemigroup[VL], + eqv: VR =:= VL) extends Mul[VL, UL, VR, UR]: + type VO = VL + type UO = UOp + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.times(ql.value, eqv(qr.value)).withUnit[UO] + + class Mul2V2U[VL, UL, VR, UR, VOp, UOp]( + alg: MultiplicativeSemigroup[VOp], + icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UR]]) extends Mul[VL, UL, VR, UR]: + type VO = VOp + type UO = UOp + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.times(icl(ql).value, icr(qr).value).withUnit[UO] + From 24509e0193b1a030ac6e74bd5d93cceda0da5c70 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 11:50:21 -0700 Subject: [PATCH 11/35] named div --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../main/scala/coulomb/ops/standard/div.scala | 78 +++++++++++-------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index e284629a3..22eecf1e7 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -20,5 +20,6 @@ package coulomb.ops.standard export add.given export sub.given export mul.given +export div.given export pow.given export simplify.given diff --git a/core/src/main/scala/coulomb/ops/standard/div.scala b/core/src/main/scala/coulomb/ops/standard/div.scala index d7899b4db..db3174761 100644 --- a/core/src/main/scala/coulomb/ops/standard/div.scala +++ b/core/src/main/scala/coulomb/ops/standard/div.scala @@ -16,36 +16,48 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion - -import algebra.ring.MultiplicativeGroup - -import coulomb.{`/`, Quantity, withUnit} -import coulomb.ops.{Div, SimplifiedUnit, ValueResolution} - -transparent inline given ctx_div_1V2U[VL, UL, VR, UR](using - // https://github.com/lampepfl/dotty/issues/14585 - eqv: VR =:= VL, - alg: MultiplicativeGroup[VL], - su: SimplifiedUnit[UL / UR] - ): Div[VL, UL, VR, UR] = - new Div[VL, UL, VR, UR]: - type VO = VL - type UO = su.UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.div(ql.value, eqv(qr.value)).withUnit[UO] - -transparent inline given ctx_div_2V2U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UR]], - alg: MultiplicativeGroup[vres.VO], - su: SimplifiedUnit[UL / UR] - ): Div[VL, UL, VR, UR] = - new Div[VL, UL, VR, UR]: - type VO = vres.VO - type UO = su.UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.div(icl(ql).value, icr(qr).value).withUnit[UO] +object div: + import scala.util.NotGiven + import scala.Conversion + + import algebra.ring.MultiplicativeGroup + + import coulomb.{`/`, Quantity, withUnit} + import coulomb.ops.{Div, SimplifiedUnit, ValueResolution} + + transparent inline given ctx_div_1V2U[VL, UL, VR, UR](using + // https://github.com/lampepfl/dotty/issues/14585 + eqv: VR =:= VL, + alg: MultiplicativeGroup[VL], + su: SimplifiedUnit[UL / UR] + ): Div[VL, UL, VR, UR] = + new infra.Div1V2U[VL, UL, VR, UR, su.UO](alg, eqv) + + transparent inline given ctx_div_2V2U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UR]], + alg: MultiplicativeGroup[vres.VO], + su: SimplifiedUnit[UL / UR] + ): Div[VL, UL, VR, UR] = + new infra.Div2V2U[VL, UL, VR, UR, vres.VO, su.UO](alg, icl, icr) + + object infra: + class Div1V2U[VL, UL, VR, UR, UOp]( + alg: MultiplicativeGroup[VL], + eqv: VR =:= VL) extends Div[VL, UL, VR, UR]: + type VO = VL + type UO = UOp + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.div(ql.value, eqv(qr.value)).withUnit[UO] + + class Div2V2U[VL, UL, VR, UR, VOp, UOp]( + alg: MultiplicativeGroup[VOp], + icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UR]]) extends Div[VL, UL, VR, UR]: + type VO = VOp + type UO = UOp + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.div(icl(ql).value, icr(qr).value).withUnit[UO] + From 3e4661a78195da1db33bd2eddf2f746a5a63fb2e Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 12:24:59 -0700 Subject: [PATCH 12/35] named tquot and tpow --- .../main/scala/coulomb/ops/standard/all.scala | 2 + .../main/scala/coulomb/ops/standard/pow.scala | 16 ++-- .../scala/coulomb/ops/standard/tpow.scala | 33 ++++---- .../scala/coulomb/ops/standard/tquot.scala | 77 +++++++++++-------- 4 files changed, 72 insertions(+), 56 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index 22eecf1e7..eec32535e 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -21,5 +21,7 @@ export add.given export sub.given export mul.given export div.given +export tquot.given export pow.given +export tpow.given export simplify.given diff --git a/core/src/main/scala/coulomb/ops/standard/pow.scala b/core/src/main/scala/coulomb/ops/standard/pow.scala index 07e5f00c4..f544983e5 100644 --- a/core/src/main/scala/coulomb/ops/standard/pow.scala +++ b/core/src/main/scala/coulomb/ops/standard/pow.scala @@ -16,17 +16,17 @@ package coulomb.ops.standard -import scala.util.NotGiven +object pow: + import scala.util.NotGiven -import algebra.ring.MultiplicativeSemigroup -import algebra.ring.MultiplicativeGroup + import algebra.ring.MultiplicativeSemigroup + import algebra.ring.MultiplicativeGroup -import coulomb.{`^`, Quantity, withUnit} -import coulomb.ops.{Pow, SimplifiedUnit} -import coulomb.rational.typeexpr -import coulomb.ops.algebra.FractionalPower + import coulomb.{`^`, Quantity, withUnit} + import coulomb.ops.{Pow, SimplifiedUnit} + import coulomb.rational.typeexpr + import coulomb.ops.algebra.FractionalPower -object pow: transparent inline given ctx_pow_FractionalPower[V, U, E](using alg: FractionalPower[V], su: SimplifiedUnit[U ^ E] diff --git a/core/src/main/scala/coulomb/ops/standard/tpow.scala b/core/src/main/scala/coulomb/ops/standard/tpow.scala index fe6b808c3..5730f761e 100644 --- a/core/src/main/scala/coulomb/ops/standard/tpow.scala +++ b/core/src/main/scala/coulomb/ops/standard/tpow.scala @@ -16,20 +16,23 @@ package coulomb.ops.standard -import scala.util.NotGiven +object tpow: + import scala.util.NotGiven -import coulomb.{`^`, Quantity, withUnit} -import coulomb.ops.{TPow, SimplifiedUnit} -import coulomb.ops.algebra.TruncatingPower -import coulomb.rational.typeexpr + import coulomb.{`^`, Quantity, withUnit} + import coulomb.ops.{TPow, SimplifiedUnit} + import coulomb.ops.algebra.TruncatingPower + import coulomb.rational.typeexpr -transparent inline given ctx_quantity_tpow[V, U, E](using - alg: TruncatingPower[V], - su: SimplifiedUnit[U ^ E] - ): TPow[V, U, E] = - val e = typeexpr.double[E] - new TPow[V, U, E]: - type VO = V - type UO = su.UO - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.tpow(q.value, e).withUnit[UO] + transparent inline given ctx_quantity_tpow[V, U, E](using + alg: TruncatingPower[V], + su: SimplifiedUnit[U ^ E] + ): TPow[V, U, E] = + new infra.TPowNC[V, U, E, su.UO](alg, typeexpr.double[E]) + + object infra: + class TPowNC[V, U, E, UOp](alg: TruncatingPower[V], e: Double) extends TPow[V, U, E]: + type VO = V + type UO = UOp + def apply(q: Quantity[V, U]): Quantity[VO, UO] = + alg.tpow(q.value, e).withUnit[UO] diff --git a/core/src/main/scala/coulomb/ops/standard/tquot.scala b/core/src/main/scala/coulomb/ops/standard/tquot.scala index b7d8c4f8e..816d637f4 100644 --- a/core/src/main/scala/coulomb/ops/standard/tquot.scala +++ b/core/src/main/scala/coulomb/ops/standard/tquot.scala @@ -16,36 +16,47 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion - -import algebra.ring.TruncatedDivision - -import coulomb.{`/`, Quantity, withUnit} -import coulomb.ops.{TQuot, SimplifiedUnit, ValueResolution} - -transparent inline given ctx_tquot_1V2U[VL, UL, VR, UR](using - // https://github.com/lampepfl/dotty/issues/14585 - eqv: VR =:= VL, - alg: TruncatedDivision[VL], - su: SimplifiedUnit[UL / UR] - ): TQuot[VL, UL, VR, UR] = - new TQuot[VL, UL, VR, UR]: - type VO = VL - type UO = su.UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.tquot(ql.value, eqv(qr.value)).withUnit[UO] - -transparent inline given ctx_tquot_2V2U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UR]], - alg: TruncatedDivision[vres.VO], - su: SimplifiedUnit[UL / UR] - ): TQuot[VL, UL, VR, UR] = - new TQuot[VL, UL, VR, UR]: - type VO = vres.VO - type UO = su.UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.tquot(icl(ql).value, icr(qr).value).withUnit[UO] +object tquot: + import scala.util.NotGiven + import scala.Conversion + + import algebra.ring.TruncatedDivision + + import coulomb.{`/`, Quantity, withUnit} + import coulomb.ops.{TQuot, SimplifiedUnit, ValueResolution} + + transparent inline given ctx_tquot_1V2U[VL, UL, VR, UR](using + // https://github.com/lampepfl/dotty/issues/14585 + eqv: VR =:= VL, + alg: TruncatedDivision[VL], + su: SimplifiedUnit[UL / UR] + ): TQuot[VL, UL, VR, UR] = + new infra.TQuot1V2U[VL, UL, VR, UR, su.UO](alg, eqv) + + transparent inline given ctx_tquot_2V2U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UR]], + alg: TruncatedDivision[vres.VO], + su: SimplifiedUnit[UL / UR] + ): TQuot[VL, UL, VR, UR] = + new infra.TQuot2V2U[VL, UL, VR, UR, vres.VO, su.UO](alg, icl, icr) + + object infra: + class TQuot1V2U[VL, UL, VR, UR, UOp]( + alg: TruncatedDivision[VL], + eqv: VR =:= VL) extends TQuot[VL, UL, VR, UR]: + type VO = VL + type UO = UOp + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.tquot(ql.value, eqv(qr.value)).withUnit[UO] + + class TQuot2V2U[VL, UL, VR, UR, VOp, UOp]( + alg: TruncatedDivision[VOp], + icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UR]]) extends TQuot[VL, UL, VR, UR]: + type VO = VOp + type UO = UOp + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = + alg.tquot(icl(ql).value, icr(qr).value).withUnit[UO] From 6d3dc7cfb61007c0a415fd22c09b5d38c9ec3894 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 12:44:21 -0700 Subject: [PATCH 13/35] named ord --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../main/scala/coulomb/ops/standard/ord.scala | 103 ++++++++++-------- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index eec32535e..c88818e98 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -24,4 +24,5 @@ export div.given export tquot.given export pow.given export tpow.given +export ord.given export simplify.given diff --git a/core/src/main/scala/coulomb/ops/standard/ord.scala b/core/src/main/scala/coulomb/ops/standard/ord.scala index f21d6c38a..79f90c462 100644 --- a/core/src/main/scala/coulomb/ops/standard/ord.scala +++ b/core/src/main/scala/coulomb/ops/standard/ord.scala @@ -16,54 +16,67 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object ord: + import scala.util.NotGiven + import scala.Conversion -import cats.kernel.Order + import cats.kernel.Order -import coulomb.Quantity -import coulomb.ops.{Ord, ValueResolution} + import coulomb.Quantity + import coulomb.ops.{Ord, ValueResolution} -transparent inline given ctx_ord_1V1U[VL, UL, VR, UR](using - // https://github.com/lampepfl/dotty/issues/14585 - eqv: VR =:= VL, - equ: UR =:= UL, - ord: Order[VL] - ): Ord[VL, UL, VR, UR] = - new Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(ql.value, eqv(qr.value)) + transparent inline given ctx_ord_1V1U[VL, UL, VR, UR](using + // https://github.com/lampepfl/dotty/issues/14585 + eqv: VR =:= VL, + equ: UR =:= UL, + ord: Order[VL] + ): Ord[VL, UL, VR, UR] = + new infra.Ord1V1U[VL, UL, VR, UR](ord, eqv) -transparent inline given ctx_ord_1V2U[VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], - ord: Order[VL] - ): Ord[VL, UL, VR, UR] = - new Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(ql.value, icr(qr).value) + transparent inline given ctx_ord_1V2U[VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], + ord: Order[VL] + ): Ord[VL, UL, VR, UR] = + new infra.Ord1V2U[VL, UL, VR, UR](ord, icr) -transparent inline given ctx_ord_2V1U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - ord: Order[vres.VO] - ): Ord[VL, UL, VR, UR] = - new Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(icl(ql).value, icr(qr).value) + transparent inline given ctx_ord_2V1U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + ord: Order[vres.VO] + ): Ord[VL, UL, VR, UR] = + new infra.Ord2V2U[VL, UL, VR, UR, vres.VO](ord, icl, icr) -transparent inline given ctx_ord_2V2U[VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - vres: ValueResolution[VL, VR], - icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - ord: Order[vres.VO] - ): Ord[VL, UL, VR, UR] = - new Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(icl(ql).value, icr(qr).value) + transparent inline given ctx_ord_2V2U[VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + vres: ValueResolution[VL, VR], + icl: Conversion[Quantity[VL, UL], Quantity[vres.VO, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + ord: Order[vres.VO] + ): Ord[VL, UL, VR, UR] = + new infra.Ord2V2U[VL, UL, VR, UR, vres.VO](ord, icl, icr) + + object infra: + class Ord1V1U[VL, UL, VR, UR]( + ord: Order[VL], + eqv: VR =:= VL) extends Ord[VL, UL, VR, UR]: + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = + ord.compare(ql.value, eqv(qr.value)) + + class Ord1V2U[VL, UL, VR, UR]( + ord: Order[VL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends Ord[VL, UL, VR, UR]: + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = + ord.compare(ql.value, icr(qr).value) + + class Ord2V2U[VL, UL, VR, UR, VOp]( + ord: Order[VOp], + icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends Ord[VL, UL, VR, UR]: + def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = + ord.compare(icl(ql).value, icr(qr).value) From fcd5dc13e4f57353725f997c5e866e687bc300a9 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 13:07:58 -0700 Subject: [PATCH 14/35] move simplification --- .../simplify.scala => simplification/standard.scala} | 5 +++-- core/src/main/scala/coulomb/ops/standard/all.scala | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) rename core/src/main/scala/coulomb/ops/{standard/simplify.scala => simplification/standard.scala} (95%) diff --git a/core/src/main/scala/coulomb/ops/standard/simplify.scala b/core/src/main/scala/coulomb/ops/simplification/standard.scala similarity index 95% rename from core/src/main/scala/coulomb/ops/standard/simplify.scala rename to core/src/main/scala/coulomb/ops/simplification/standard.scala index ec6d6bef8..de9f736e7 100644 --- a/core/src/main/scala/coulomb/ops/standard/simplify.scala +++ b/core/src/main/scala/coulomb/ops/simplification/standard.scala @@ -14,9 +14,9 @@ * limitations under the License. */ -package coulomb.ops.standard +package coulomb.ops.simplification -object simplify: +object standard: import coulomb.ops.SimplifiedUnit transparent inline given ctx_SimplifiedUnit[U]: SimplifiedUnit[U] = @@ -32,3 +32,4 @@ object simplify: import quotes.reflect.* coulomb.infra.meta.simplify(TypeRepr.of[U]).asType match case '[uo] => '{ new SU[U, uo] } + diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index c88818e98..edb903b43 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -25,4 +25,6 @@ export tquot.given export pow.given export tpow.given export ord.given -export simplify.given + +// will be exported via policies +export coulomb.ops.simplification.standard.given From f2ca846920f5181fc8c5b0e445081ab5ac9b5738 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 13:38:36 -0700 Subject: [PATCH 15/35] named deltasub --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../scala/coulomb/ops/standard/deltasub.scala | 116 ++++++++++-------- 2 files changed, 65 insertions(+), 52 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index edb903b43..36aee50c2 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -25,6 +25,7 @@ export tquot.given export pow.given export tpow.given export ord.given +export deltasub.given // will be exported via policies export coulomb.ops.simplification.standard.given diff --git a/core/src/main/scala/coulomb/ops/standard/deltasub.scala b/core/src/main/scala/coulomb/ops/standard/deltasub.scala index 710c76a89..ca30ddab3 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltasub.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltasub.scala @@ -16,61 +16,73 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object deltasub: + import scala.util.NotGiven + import scala.Conversion -import algebra.ring.AdditiveGroup + import algebra.ring.AdditiveGroup -import coulomb.* -import coulomb.ops.{DeltaSub, ValueResolution} + import coulomb.* + import coulomb.ops.{DeltaSub, ValueResolution} -transparent inline given ctx_deltasub_1V1U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - equ: UR =:= UL, - alg: AdditiveGroup[VL] - ): DeltaSub[B, VL, UL, VR, UR] = - new DeltaSub[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(ql.value, eqv(qr.value)).withUnit[UO] + transparent inline given ctx_deltasub_1V1U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + equ: UR =:= UL, + alg: AdditiveGroup[VL] + ): DeltaSub[B, VL, UL, VR, UR] = + new infra.DeltaSub1V1U[B, VL, UL, VR, UR](alg, eqv) -transparent inline given ctx_deltasub_1V2U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]], - alg: AdditiveGroup[VL] - ): DeltaSub[B, VL, UL, VR, UR] = - new DeltaSub[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(ql.value, icr(qr).value).withUnit[UO] + transparent inline given ctx_deltasub_1V2U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]], + alg: AdditiveGroup[VL] + ): DeltaSub[B, VL, UL, VR, UR] = + new infra.DeltaSub1V2U[B, VL, UL, VR, UR](alg, icr) -transparent inline given ctx_deltasub_2V1U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], - alg: AdditiveGroup[vres.VO] - ): DeltaSub[B, VL, UL, VR, UR] = - new DeltaSub[B, VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] + transparent inline given ctx_deltasub_2V1U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], + alg: AdditiveGroup[vres.VO] + ): DeltaSub[B, VL, UL, VR, UR] = + new infra.DeltaSub2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + + transparent inline given ctx_deltasub_2V2U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], + alg: AdditiveGroup[vres.VO] + ): DeltaSub[B, VL, UL, VR, UR] = + new infra.DeltaSub2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + + object infra: + class DeltaSub1V1U[B, VL, UL, VR, UR]( + alg: AdditiveGroup[VL], + eqv: VR =:= VL) extends DeltaSub[B, VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = + alg.minus(ql.value, eqv(qr.value)).withUnit[UO] + + class DeltaSub1V2U[B, VL, UL, VR, UR]( + alg: AdditiveGroup[VL], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]]) extends DeltaSub[B, VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = + alg.minus(ql.value, icr(qr).value).withUnit[UO] + + class DeltaSub2V2U[B, VL, UL, VR, UR, VOp]( + alg: AdditiveGroup[VOp], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VOp, UL, B]]) extends DeltaSub[B, VL, UL, VR, UR]: + type VO = VOp + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = + alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] -transparent inline given ctx_deltasub_2V2U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], - alg: AdditiveGroup[vres.VO] - ): DeltaSub[B, VL, UL, VR, UR] = - new DeltaSub[B, VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] From 5aa2abe209e3ff27a9e09bd70bf030379f990946 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 13:49:12 -0700 Subject: [PATCH 16/35] named deltasubq --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../coulomb/ops/standard/deltasubq.scala | 115 ++++++++++-------- 2 files changed, 64 insertions(+), 52 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index 36aee50c2..c14181385 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -26,6 +26,7 @@ export pow.given export tpow.given export ord.given export deltasub.given +export deltasubq.given // will be exported via policies export coulomb.ops.simplification.standard.given diff --git a/core/src/main/scala/coulomb/ops/standard/deltasubq.scala b/core/src/main/scala/coulomb/ops/standard/deltasubq.scala index 6afdc4f0f..111e7b9df 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltasubq.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltasubq.scala @@ -16,62 +16,73 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object deltasubq: + import scala.util.NotGiven + import scala.Conversion -import algebra.ring.AdditiveGroup + import algebra.ring.AdditiveGroup -import coulomb.* -import coulomb.ops.{DeltaSubQ, ValueResolution} + import coulomb.* + import coulomb.ops.{DeltaSubQ, ValueResolution} -transparent inline given ctx_deltasubq_1V1U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - equ: UR =:= UL, - alg: AdditiveGroup[VL] - ): DeltaSubQ[B, VL, UL, VR, UR] = - new DeltaSubQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(ql.value, eqv(qr.value)).withDeltaUnit[UO, B] + transparent inline given ctx_deltasubq_1V1U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + equ: UR =:= UL, + alg: AdditiveGroup[VL] + ): DeltaSubQ[B, VL, UL, VR, UR] = + new infra.DeltaSubQ1V1U[B, VL, UL, VR, UR](alg, eqv) -transparent inline given ctx_deltasubq_1V2U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], - alg: AdditiveGroup[VL] - ): DeltaSubQ[B, VL, UL, VR, UR] = - new DeltaSubQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(ql.value, icr(qr).value).withDeltaUnit[UO, B] + transparent inline given ctx_deltasubq_1V2U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], + alg: AdditiveGroup[VL] + ): DeltaSubQ[B, VL, UL, VR, UR] = + new infra.DeltaSubQ1V2U[B, VL, UL, VR, UR](alg, icr) -transparent inline given ctx_deltasubq_2V1U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveGroup[vres.VO] - ): DeltaSubQ[B, VL, UL, VR, UR] = - new DeltaSubQ[B, VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] + transparent inline given ctx_deltasubq_2V1U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + alg: AdditiveGroup[vres.VO] + ): DeltaSubQ[B, VL, UL, VR, UR] = + new infra.DeltaSubQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) -transparent inline given ctx_deltasubq_2V2U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveGroup[vres.VO] - ): DeltaSubQ[B, VL, UL, VR, UR] = - new DeltaSubQ[B, VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] + transparent inline given ctx_deltasubq_2V2U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + alg: AdditiveGroup[vres.VO] + ): DeltaSubQ[B, VL, UL, VR, UR] = + new infra.DeltaSubQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + + object infra: + class DeltaSubQ1V1U[B, VL, UL, VR, UR]( + alg: AdditiveGroup[VL], + eqv: VR =:= VL) extends DeltaSubQ[B, VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = + alg.minus(ql.value, eqv(qr.value)).withDeltaUnit[UO, B] + + class DeltaSubQ1V2U[B, VL, UL, VR, UR]( + alg: AdditiveGroup[VL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends DeltaSubQ[B, VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = + alg.minus(ql.value, icr(qr).value).withDeltaUnit[UO, B] + + class DeltaSubQ2V2U[B, VL, UL, VR, UR, VOp]( + alg: AdditiveGroup[VOp], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends DeltaSubQ[B, VL, UL, VR, UR]: + type VO = VOp + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = + alg.minus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] From 1cdd9b4e014c43120294cc66faecfa6540e18a26 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 13:55:46 -0700 Subject: [PATCH 17/35] named deltaaddq --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../coulomb/ops/standard/deltaaddq.scala | 114 ++++++++++-------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index c14181385..98cf9a411 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -27,6 +27,7 @@ export tpow.given export ord.given export deltasub.given export deltasubq.given +export deltaaddq.given // will be exported via policies export coulomb.ops.simplification.standard.given diff --git a/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala b/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala index 322fb7fe4..b3bc7b64f 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala @@ -16,64 +16,72 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object deltaaddq: + import scala.util.NotGiven + import scala.Conversion -import algebra.ring.AdditiveSemigroup + import algebra.ring.AdditiveSemigroup -import coulomb.* -import coulomb.ops.{DeltaAddQ, ValueResolution} + import coulomb.* + import coulomb.ops.{DeltaAddQ, ValueResolution} -transparent inline given ctx_deltaaddq_1V1U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - equ: UR =:= UL, - alg: AdditiveSemigroup[VL] - ): DeltaAddQ[B, VL, UL, VR, UR] = - new DeltaAddQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(ql.value, eqv(qr.value)).withDeltaUnit[UO, B] + transparent inline given ctx_deltaaddq_1V1U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + equ: UR =:= UL, + alg: AdditiveSemigroup[VL] + ): DeltaAddQ[B, VL, UL, VR, UR] = + new infra.DeltaAddQ1V1U[B, VL, UL, VR, UR](alg, eqv) -transparent inline given ctx_deltaaddq_1V2U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], - alg: AdditiveSemigroup[VL] - ): DeltaAddQ[B, VL, UL, VR, UR] = - new DeltaAddQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(ql.value, icr(qr).value).withDeltaUnit[UO, B] + transparent inline given ctx_deltaaddq_1V2U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], + alg: AdditiveSemigroup[VL] + ): DeltaAddQ[B, VL, UL, VR, UR] = + new infra.DeltaAddQ1V2U[B, VL, UL, VR, UR](alg, icr) -transparent inline given ctx_deltaaddq_2V1U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveSemigroup[vres.VO] - ): DeltaAddQ[B, VL, UL, VR, UR] = - new DeltaAddQ[B, VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] - -transparent inline given ctx_deltaaddq_2V2U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], - alg: AdditiveSemigroup[vres.VO] - ): DeltaAddQ[B, VL, UL, VR, UR] = - new DeltaAddQ[B, VL, UL, VR, UR]: - type VO = vres.VO - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] + transparent inline given ctx_deltaaddq_2V1U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + alg: AdditiveSemigroup[vres.VO] + ): DeltaAddQ[B, VL, UL, VR, UR] = + new infra.DeltaAddQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + transparent inline given ctx_deltaaddq_2V2U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], + alg: AdditiveSemigroup[vres.VO] + ): DeltaAddQ[B, VL, UL, VR, UR] = + new infra.DeltaAddQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + object infra: + class DeltaAddQ1V1U[B, VL, UL, VR, UR]( + alg: AdditiveSemigroup[VL], + eqv: VR =:= VL) extends DeltaAddQ[B, VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = + alg.plus(ql.value, eqv(qr.value)).withDeltaUnit[UO, B] + + class DeltaAddQ1V2U[B, VL, UL, VR, UR]( + alg: AdditiveSemigroup[VL], + icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends DeltaAddQ[B, VL, UL, VR, UR]: + type VO = VL + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = + alg.plus(ql.value, icr(qr).value).withDeltaUnit[UO, B] + class DeltaAddQ2V2U[B, VL, UL, VR, UR, VOp]( + alg: AdditiveSemigroup[VOp], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], + icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends DeltaAddQ[B, VL, UL, VR, UR]: + type VO = VOp + type UO = UL + def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = + alg.plus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] From d7e3a9dcb6fddd0831b961ac06656ea07fc45a64 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 14:07:13 -0700 Subject: [PATCH 18/35] named deltaord --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../scala/coulomb/ops/standard/deltaord.scala | 102 ++++++++++-------- 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index 98cf9a411..cf5ce6bc4 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -28,6 +28,7 @@ export ord.given export deltasub.given export deltasubq.given export deltaaddq.given +export deltaord.given // will be exported via policies export coulomb.ops.simplification.standard.given diff --git a/core/src/main/scala/coulomb/ops/standard/deltaord.scala b/core/src/main/scala/coulomb/ops/standard/deltaord.scala index 8a7ccaf49..7a3f42b72 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltaord.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltaord.scala @@ -16,53 +16,67 @@ package coulomb.ops.standard -import scala.util.NotGiven -import scala.Conversion +object deltaord: + import scala.util.NotGiven + import scala.Conversion -import cats.kernel.Order + import cats.kernel.Order -import coulomb.* -import coulomb.ops.{DeltaOrd, ValueResolution} + import coulomb.* + import coulomb.ops.{DeltaOrd, ValueResolution} -transparent inline given ctx_deltaord_1V1U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - equ: UR =:= UL, - ord: Order[VL] - ): DeltaOrd[B, VL, UL, VR, UR] = - new DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(ql.value, eqv(qr.value)) + transparent inline given ctx_deltaord_1V1U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + equ: UR =:= UL, + ord: Order[VL] + ): DeltaOrd[B, VL, UL, VR, UR] = + new infra.DeltaOrd1V1U[B, VL, UL, VR, UR](ord, eqv) -transparent inline given ctx_deltaord_1V2U[B, VL, UL, VR, UR](using - eqv: VR =:= VL, - neu: NotGiven[UR =:= UL], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]], - ord: Order[VL] - ): DeltaOrd[B, VL, UL, VR, UR] = - new DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(ql.value, icr(qr).value) + transparent inline given ctx_deltaord_1V2U[B, VL, UL, VR, UR](using + eqv: VR =:= VL, + neu: NotGiven[UR =:= UL], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]], + ord: Order[VL] + ): DeltaOrd[B, VL, UL, VR, UR] = + new infra.DeltaOrd1V2U[B, VL, UL, VR, UR](ord, icr) -transparent inline given ctx_deltaord_2V1U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - equ: UR =:= UL, - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], - ord: Order[vres.VO] - ): DeltaOrd[B, VL, UL, VR, UR] = - new DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(icl(ql).value, icr(qr).value) + transparent inline given ctx_deltaord_2V1U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + equ: UR =:= UL, + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], + ord: Order[vres.VO] + ): DeltaOrd[B, VL, UL, VR, UR] = + new infra.DeltaOrd2V2U[B, VL, UL, VR, UR, vres.VO](ord, icl, icr) + + transparent inline given ctx_deltaord_2V2U[B, VL, UL, VR, UR](using + nev: NotGiven[VR =:= VL], + neu: NotGiven[UR =:= UL], + vres: ValueResolution[VL, VR], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], + ord: Order[vres.VO] + ): DeltaOrd[B, VL, UL, VR, UR] = + new infra.DeltaOrd2V2U[B, VL, UL, VR, UR, vres.VO](ord, icl, icr) + + object infra: + class DeltaOrd1V1U[B, VL, UL, VR, UR]( + ord: Order[VL], + eqv: VR =:= VL) extends DeltaOrd[B, VL, UL, VR, UR]: + def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = + ord.compare(ql.value, eqv(qr.value)) + + class DeltaOrd1V2U[B, VL, UL, VR, UR]( + ord: Order[VL], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]]) extends DeltaOrd[B, VL, UL, VR, UR]: + def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = + ord.compare(ql.value, icr(qr).value) + + class DeltaOrd2V2U[B, VL, UL, VR, UR, VOp]( + ord: Order[VOp], + icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], + icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VOp, UL, B]]) extends DeltaOrd[B, VL, UL, VR, UR]: + def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = + ord.compare(icl(ql).value, icr(qr).value) -transparent inline given ctx_deltaord_2V2U[B, VL, UL, VR, UR](using - nev: NotGiven[VR =:= VL], - neu: NotGiven[UR =:= UL], - vres: ValueResolution[VL, VR], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[vres.VO, UL, B]], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], - ord: Order[vres.VO] - ): DeltaOrd[B, VL, UL, VR, UR] = - new DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(icl(ql).value, icr(qr).value) From 5ad20dd5cd25907cce9a3ca0e8cfe88f2b07eca9 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 14:24:27 -0700 Subject: [PATCH 19/35] named neg --- .../main/scala/coulomb/ops/standard/all.scala | 1 + .../main/scala/coulomb/ops/standard/neg.scala | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index cf5ce6bc4..e9d54d8f2 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -17,6 +17,7 @@ package coulomb.ops.standard // eventually these go in `object all` +export neg.given export add.given export sub.given export mul.given diff --git a/core/src/main/scala/coulomb/ops/standard/neg.scala b/core/src/main/scala/coulomb/ops/standard/neg.scala index 6d347c842..3d9cdbd5a 100644 --- a/core/src/main/scala/coulomb/ops/standard/neg.scala +++ b/core/src/main/scala/coulomb/ops/standard/neg.scala @@ -16,13 +16,16 @@ package coulomb.ops.standard -import algebra.ring.AdditiveGroup +object neg: + import algebra.ring.AdditiveGroup -import coulomb.{Quantity, withUnit} -import coulomb.ops.Neg + import coulomb.{Quantity, withUnit} + import coulomb.ops.Neg -inline given ctx_quantity_neg[V, U](using alg: AdditiveGroup[V]): Neg[V, U] = - new Neg[V, U]: - def apply(q: Quantity[V, U]): Quantity[V, U] = - alg.negate(q.value).withUnit[U] + inline given ctx_quantity_neg[V, U](using alg: AdditiveGroup[V]): Neg[V, U] = + new infra.NegNC[V, U](alg) + object infra: + class NegNC[V, U](alg: AdditiveGroup[V]) extends Neg[V, U]: + def apply(q: Quantity[V, U]): Quantity[V, U] = + alg.negate(q.value).withUnit[U] From 06671bfee1fd9b70aae0609ad913270af9610366 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Sat, 2 Apr 2022 14:59:12 -0700 Subject: [PATCH 20/35] clean up rational.typeexpr --- core/src/main/scala/coulomb/infra/meta.scala | 42 ------------- .../scala/coulomb/rational/rational.scala | 60 +++++++++++++++---- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/core/src/main/scala/coulomb/infra/meta.scala b/core/src/main/scala/coulomb/infra/meta.scala index 3154642c8..fb76f141a 100644 --- a/core/src/main/scala/coulomb/infra/meta.scala +++ b/core/src/main/scala/coulomb/infra/meta.scala @@ -31,48 +31,6 @@ object meta: case v if (v == 1) => '{ Rational.const1 } case _ => '{ Rational(${Expr(r.n)}, ${Expr(r.d)}) } - def teToRational[E](using Quotes, Type[E]): Expr[Rational] = - import quotes.reflect.* - val rationalTE(v) = TypeRepr.of[E] - Expr(v) - - def teToBigInt[E](using Quotes, Type[E]): Expr[BigInt] = - import quotes.reflect.* - val bigintTE(v) = TypeRepr.of[E] - Expr(v) - - def teToDouble[E](using Quotes, Type[E]): Expr[Double] = - import quotes.reflect.* - val rationalTE(v) = TypeRepr.of[E] - Expr(v.toDouble) - - def teToNonNegInt[E](using Quotes, Type[E]): Expr[coulomb.rational.typeexpr.NonNegInt[E]] = - import quotes.reflect.* - val rationalTE(v) = TypeRepr.of[E] - if ((v.d == 1) && (v.n >= 0) && (v.n.isValidInt)) then - '{ new coulomb.rational.typeexpr.NonNegInt[E] { val value = ${Expr(v.n.toInt)} } } - else - report.error(s"type expr ${typestr(TypeRepr.of[E])} is not a non-negative Int") - '{ new coulomb.rational.typeexpr.NonNegInt[E] { val value = 0 } } - - def teToPosInt[E](using Quotes, Type[E]): Expr[coulomb.rational.typeexpr.PosInt[E]] = - import quotes.reflect.* - val rationalTE(v) = TypeRepr.of[E] - if ((v.d == 1) && (v.n > 0) && (v.n.isValidInt)) then - '{ new coulomb.rational.typeexpr.PosInt[E] { val value = ${Expr(v.n.toInt)} } } - else - report.error(s"type expr ${typestr(TypeRepr.of[E])} is not a positive Int") - '{ new coulomb.rational.typeexpr.PosInt[E] { val value = 0 } } - - def teToInt[E](using Quotes, Type[E]): Expr[coulomb.rational.typeexpr.AllInt[E]] = - import quotes.reflect.* - val rationalTE(v) = TypeRepr.of[E] - if ((v.d == 1) && (v.n.isValidInt)) then - '{ new coulomb.rational.typeexpr.AllInt[E] { val value = ${Expr(v.n.toInt)} } } - else - report.error(s"type expr ${typestr(TypeRepr.of[E])} is not an Int") - '{ new coulomb.rational.typeexpr.AllInt[E] { val value = 0 } } - object rationalTE: def unapply(using Quotes)(tr: quotes.reflect.TypeRepr): Option[Rational] = import quotes.reflect.* diff --git a/core/src/main/scala/coulomb/rational/rational.scala b/core/src/main/scala/coulomb/rational/rational.scala index d4ec8dd0d..9426868ca 100644 --- a/core/src/main/scala/coulomb/rational/rational.scala +++ b/core/src/main/scala/coulomb/rational/rational.scala @@ -144,30 +144,70 @@ end Rational /** Obtaining values from Rational type expressions */ object typeexpr: import scala.annotation.implicitNotFound - import coulomb.infra.meta inline def rational[E]: Rational = ${ meta.teToRational[E] } inline def bigInt[E]: BigInt = ${ meta.teToBigInt[E] } inline def double[E]: Double = ${ meta.teToDouble[E] } @implicitNotFound("type expr ${E} is not a non-negative Int") - abstract class NonNegInt[E]: - val value: Int - + class NonNegInt[E](val value: Int) object NonNegInt: // interesting, this has to be 'transparent' to work with NotGiven transparent inline given ctx_NonNegInt[E]: NonNegInt[E] = ${ meta.teToNonNegInt[E] } @implicitNotFound("type expr ${E} is not a positive Int") - abstract class PosInt[E]: - val value: Int - + class PosInt[E](val value: Int) object PosInt: transparent inline given ctx_PosInt[E]: PosInt[E] = ${ meta.teToPosInt[E] } @implicitNotFound("type expr ${E} is not an Int") - abstract class AllInt[E]: - val value: Int - + class AllInt[E](val value: Int) object AllInt: transparent inline given ctx_AllInt[E]: AllInt[E] = ${ meta.teToInt[E] } + + object meta: + import scala.quoted.* + import scala.language.implicitConversions + import coulomb.infra.meta.{rationalTE, bigintTE, ctx_RationalToExpr, typestr} + + def teToRational[E](using Quotes, Type[E]): Expr[Rational] = + import quotes.reflect.* + val rationalTE(v) = TypeRepr.of[E] + Expr(v) + + def teToBigInt[E](using Quotes, Type[E]): Expr[BigInt] = + import quotes.reflect.* + val bigintTE(v) = TypeRepr.of[E] + Expr(v) + + def teToDouble[E](using Quotes, Type[E]): Expr[Double] = + import quotes.reflect.* + val rationalTE(v) = TypeRepr.of[E] + Expr(v.toDouble) + + def teToNonNegInt[E](using Quotes, Type[E]): Expr[NonNegInt[E]] = + import quotes.reflect.* + val rationalTE(v) = TypeRepr.of[E] + if ((v.d == 1) && (v.n >= 0) && (v.n.isValidInt)) then + '{ new NonNegInt[E](${Expr(v.n.toInt)})} + else + report.error(s"type expr ${typestr(TypeRepr.of[E])} is not a non-negative Int") + '{ new NonNegInt[E](0) } + + def teToPosInt[E](using Quotes, Type[E]): Expr[PosInt[E]] = + import quotes.reflect.* + val rationalTE(v) = TypeRepr.of[E] + if ((v.d == 1) && (v.n > 0) && (v.n.isValidInt)) then + '{ new PosInt[E](${Expr(v.n.toInt)}) } + else + report.error(s"type expr ${typestr(TypeRepr.of[E])} is not a positive Int") + '{ new PosInt[E](0) } + + def teToInt[E](using Quotes, Type[E]): Expr[AllInt[E]] = + import quotes.reflect.* + val rationalTE(v) = TypeRepr.of[E] + if ((v.d == 1) && (v.n.isValidInt)) then + '{ new AllInt[E](${Expr(v.n.toInt)})} + else + report.error(s"type expr ${typestr(TypeRepr.of[E])} is not an Int") + '{ new AllInt[E](0)} From d4dea8a269ff4ffbd700e63337736a623260a0b5 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Mon, 4 Apr 2022 17:06:08 -0700 Subject: [PATCH 21/35] AddNC SubNC MulNC DivNC --- core/src/main/scala/coulomb/ops/ops.scala | 8 ++-- .../main/scala/coulomb/ops/standard/add.scala | 36 ++++------------- .../main/scala/coulomb/ops/standard/div.scala | 24 +++-------- .../main/scala/coulomb/ops/standard/mul.scala | 24 +++-------- .../scala/coulomb/ops/standard/named.scala | 24 +++++++++++ .../ops/standard/optimizations/double.scala | 40 ++++--------------- .../ops/standard/optimizations/float.scala | 38 ++++-------------- .../main/scala/coulomb/ops/standard/sub.scala | 36 ++++------------- core/src/main/scala/coulomb/quantity.scala | 8 ++-- 9 files changed, 75 insertions(+), 163 deletions(-) create mode 100644 core/src/main/scala/coulomb/ops/standard/named.scala diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index a6109914d..5174d03a1 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -28,25 +28,25 @@ abstract class Neg[V, U]: abstract class Add[VL, UL, VR, UR]: type VO type UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] + val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VO, UO] @implicitNotFound("Subtraction not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class Sub[VL, UL, VR, UR]: type VO type UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] + val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VO, UO] @implicitNotFound("Multiplication not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class Mul[VL, UL, VR, UR]: type VO type UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] + val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VO, UO] @implicitNotFound("Division not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class Div[VL, UL, VR, UR]: type VO type UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] + val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VO, UO] @implicitNotFound("Truncating Division not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class TQuot[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/add.scala b/core/src/main/scala/coulomb/ops/standard/add.scala index ebeccc85f..8ebf4ad64 100644 --- a/core/src/main/scala/coulomb/ops/standard/add.scala +++ b/core/src/main/scala/coulomb/ops/standard/add.scala @@ -25,13 +25,15 @@ object add: import coulomb.{Quantity, withUnit} import coulomb.ops.{Add, ValueResolution} + import infra.AddNC + transparent inline given ctx_add_1V1U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, equ: UR =:= UL, alg: AdditiveSemigroup[VL] ): Add[VL, UL, VR, UR] = - new infra.Add1V1U[VL, UL, VR, UR](alg, eqv) + new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(ql.value, eqv(qr.value)).withUnit[UL]) transparent inline given ctx_add_1V2U[VL, UL, VR, UR](using eqv: VR =:= VL, @@ -39,7 +41,7 @@ object add: icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], alg: AdditiveSemigroup[VL] ): Add[VL, UL, VR, UR] = - new infra.Add1V2U[VL, UL, VR, UR](alg, icr) + new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(ql.value, icr(qr).value).withUnit[UL]) transparent inline given ctx_add_2V1U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -49,7 +51,7 @@ object add: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveSemigroup[vres.VO] ): Add[VL, UL, VR, UR] = - new infra.Add2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) transparent inline given ctx_add_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -59,31 +61,9 @@ object add: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveSemigroup[vres.VO] ): Add[VL, UL, VR, UR] = - new infra.Add2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) object infra: - class Add1V1U[VL, UL, VR, UR]( - alg: AdditiveSemigroup[VL], - eqv: VR =:= VL) extends Add[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(ql.value, eqv(qr.value)).withUnit[UO] - - class Add1V2U[VL, UL, VR, UR]( - alg: AdditiveSemigroup[VL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends Add[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(ql.value, icr(qr).value).withUnit[UO] - - class Add2V2U[VL, UL, VR, UR, VOp]( - alg: AdditiveSemigroup[VOp], - icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends Add[VL, UL, VR, UR]: + class AddNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Add[VL, UL, VR, UR]: type VO = VOp - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.plus(icl(ql).value, icr(qr).value).withUnit[UO] - + type UO = UOp diff --git a/core/src/main/scala/coulomb/ops/standard/div.scala b/core/src/main/scala/coulomb/ops/standard/div.scala index db3174761..24d476ce3 100644 --- a/core/src/main/scala/coulomb/ops/standard/div.scala +++ b/core/src/main/scala/coulomb/ops/standard/div.scala @@ -25,13 +25,15 @@ object div: import coulomb.{`/`, Quantity, withUnit} import coulomb.ops.{Div, SimplifiedUnit, ValueResolution} + import infra.DivNC + transparent inline given ctx_div_1V2U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, alg: MultiplicativeGroup[VL], su: SimplifiedUnit[UL / UR] ): Div[VL, UL, VR, UR] = - new infra.Div1V2U[VL, UL, VR, UR, su.UO](alg, eqv) + new DivNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.div(ql.value, eqv(qr.value)).withUnit[su.UO]) transparent inline given ctx_div_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -41,23 +43,9 @@ object div: alg: MultiplicativeGroup[vres.VO], su: SimplifiedUnit[UL / UR] ): Div[VL, UL, VR, UR] = - new infra.Div2V2U[VL, UL, VR, UR, vres.VO, su.UO](alg, icl, icr) + new DivNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.div(icl(ql).value, icr(qr).value).withUnit[su.UO]) object infra: - class Div1V2U[VL, UL, VR, UR, UOp]( - alg: MultiplicativeGroup[VL], - eqv: VR =:= VL) extends Div[VL, UL, VR, UR]: - type VO = VL - type UO = UOp - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.div(ql.value, eqv(qr.value)).withUnit[UO] - - class Div2V2U[VL, UL, VR, UR, VOp, UOp]( - alg: MultiplicativeGroup[VOp], - icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UR]]) extends Div[VL, UL, VR, UR]: + class DivNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Div[VL, UL, VR, UR]: type VO = VOp - type UO = UOp - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.div(icl(ql).value, icr(qr).value).withUnit[UO] - + type UO = UOp diff --git a/core/src/main/scala/coulomb/ops/standard/mul.scala b/core/src/main/scala/coulomb/ops/standard/mul.scala index 15ad7b244..2db807101 100644 --- a/core/src/main/scala/coulomb/ops/standard/mul.scala +++ b/core/src/main/scala/coulomb/ops/standard/mul.scala @@ -25,13 +25,15 @@ object mul: import coulomb.{`*`, Quantity, withUnit} import coulomb.ops.{Mul, SimplifiedUnit, ValueResolution} + import infra.MulNC + transparent inline given ctx_mul_1V2U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, alg: MultiplicativeSemigroup[VL], su: SimplifiedUnit[UL * UR] ): Mul[VL, UL, VR, UR] = - new infra.Mul1V2U[VL, UL, VR, UR, su.UO](alg, eqv) + new MulNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.times(ql.value, eqv(qr.value)).withUnit[su.UO]) transparent inline given ctx_mul_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -41,23 +43,9 @@ object mul: alg: MultiplicativeSemigroup[vres.VO], su: SimplifiedUnit[UL * UR] ): Mul[VL, UL, VR, UR] = - new infra.Mul2V2U[VL, UL, VR, UR, vres.VO, su.UO](alg, icl, icr) + new MulNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.times(icl(ql).value, icr(qr).value).withUnit[su.UO]) object infra: - class Mul1V2U[VL, UL, VR, UR, UOp]( - alg: MultiplicativeSemigroup[VL], - eqv: VR =:= VL) extends Mul[VL, UL, VR, UR]: - type VO = VL - type UO = UOp - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.times(ql.value, eqv(qr.value)).withUnit[UO] - - class Mul2V2U[VL, UL, VR, UR, VOp, UOp]( - alg: MultiplicativeSemigroup[VOp], - icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UR]]) extends Mul[VL, UL, VR, UR]: + class MulNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Mul[VL, UL, VR, UR]: type VO = VOp - type UO = UOp - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.times(icl(ql).value, icr(qr).value).withUnit[UO] - + type UO = UOp diff --git a/core/src/main/scala/coulomb/ops/standard/named.scala b/core/src/main/scala/coulomb/ops/standard/named.scala new file mode 100644 index 000000000..286a925dd --- /dev/null +++ b/core/src/main/scala/coulomb/ops/standard/named.scala @@ -0,0 +1,24 @@ +/* + * Copyright 2022 Erik Erlandson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package coulomb.ops.standard + +object named: + export add.infra.AddNC + export sub.infra.SubNC + export mul.infra.MulNC + export div.infra.DivNC + diff --git a/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala b/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala index 4816151ee..52cf44236 100644 --- a/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala +++ b/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala @@ -22,7 +22,7 @@ import scala.Conversion import coulomb.{`*`, `/`, `^`} import coulomb.{Quantity, withUnit} import coulomb.ops.* - +import coulomb.ops.standard.named.* import coulomb.conversion.coefficients.* object double: @@ -31,51 +31,27 @@ object double: def apply(q: Quantity[Double, U]): Quantity[Double, U] = (-(q.value)).withUnit[U] transparent inline given ctx_add_Double_1U[U]: Add[Double, U, Double, U] = - new Add[Double, U, Double, U]: - type VO = Double - type UO = U - def apply(ql: Quantity[Double, U], qr: Quantity[Double, U]): Quantity[Double, U] = - (ql.value + qr.value).withUnit[U] + new AddNC((ql: Quantity[Double, U], qr: Quantity[Double, U]) => (ql.value + qr.value).withUnit[U]) transparent inline given ctx_add_Double_2U[UL, UR](using Conversion[Quantity[Double, UR], Quantity[Double, UL]] ): Add[Double, UL, Double, UR] = val c = coefficientDouble[UR, UL] - new Add[Double, UL, Double, UR]: - type VO = Double - type UO = UL - def apply(ql: Quantity[Double, UL], qr: Quantity[Double, UR]): Quantity[Double, UL] = - (ql.value + (c * qr.value)).withUnit[UL] - + new AddNC((ql: Quantity[Double, UL], qr: Quantity[Double, UR]) => (ql.value + (c*qr.value)).withUnit[UL]) + transparent inline given ctx_sub_Double_1U[U]: Sub[Double, U, Double, U] = - new Sub[Double, U, Double, U]: - type VO = Double - type UO = U - def apply(ql: Quantity[Double, U], qr: Quantity[Double, U]): Quantity[Double, U] = - (ql.value - qr.value).withUnit[U] + new SubNC((ql: Quantity[Double, U], qr: Quantity[Double, U]) => (ql.value - qr.value).withUnit[U]) transparent inline given ctx_sub_Double_2U[UL, UR](using Conversion[Quantity[Double, UR], Quantity[Double, UL]] ): Sub[Double, UL, Double, UR] = val c = coefficientDouble[UR, UL] - new Sub[Double, UL, Double, UR]: - type VO = Double - type UO = UL - def apply(ql: Quantity[Double, UL], qr: Quantity[Double, UR]): Quantity[Double, UL] = - (ql.value - (c * qr.value)).withUnit[UL] + new SubNC((ql: Quantity[Double, UL], qr: Quantity[Double, UR]) => (ql.value - (c*qr.value)).withUnit[UL]) transparent inline given ctx_mul_Double_2U[UL, UR](using su: SimplifiedUnit[UL * UR]): Mul[Double, UL, Double, UR] = - new Mul[Double, UL, Double, UR]: - type VO = Double - type UO = su.UO - def apply(ql: Quantity[Double, UL], qr: Quantity[Double, UR]): Quantity[Double, UO] = - (ql.value * qr.value).withUnit[UO] + new MulNC((ql: Quantity[Double, UL], qr: Quantity[Double, UR]) => (ql.value * qr.value).withUnit[su.UO]) transparent inline given ctx_div_Double_2U[UL, UR](using su: SimplifiedUnit[UL / UR]): Div[Double, UL, Double, UR] = - new Div[Double, UL, Double, UR]: - type VO = Double - type UO = su.UO - def apply(ql: Quantity[Double, UL], qr: Quantity[Double, UR]): Quantity[Double, UO] = - (ql.value / qr.value).withUnit[UO] + new DivNC((ql: Quantity[Double, UL], qr: Quantity[Double, UR]) => (ql.value / qr.value).withUnit[su.UO]) diff --git a/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala b/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala index e0ed6c737..eda699154 100644 --- a/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala +++ b/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala @@ -22,7 +22,7 @@ import scala.Conversion import coulomb.{`*`, `/`, `^`} import coulomb.{Quantity, withUnit} import coulomb.ops.* - +import coulomb.ops.standard.named.* import coulomb.conversion.coefficients.* object float: @@ -31,51 +31,27 @@ object float: def apply(q: Quantity[Float, U]): Quantity[Float, U] = (-(q.value)).withUnit[U] transparent inline given ctx_add_Float_1U[U]: Add[Float, U, Float, U] = - new Add[Float, U, Float, U]: - type VO = Float - type UO = U - def apply(ql: Quantity[Float, U], qr: Quantity[Float, U]): Quantity[Float, U] = - (ql.value + qr.value).withUnit[U] + new AddNC((ql: Quantity[Float, U], qr: Quantity[Float, U]) => (ql.value + qr.value).withUnit[U]) transparent inline given ctx_add_Float_2U[UL, UR](using Conversion[Quantity[Float, UR], Quantity[Float, UL]] ): Add[Float, UL, Float, UR] = val c = coefficientFloat[UR, UL] - new Add[Float, UL, Float, UR]: - type VO = Float - type UO = UL - def apply(ql: Quantity[Float, UL], qr: Quantity[Float, UR]): Quantity[Float, UL] = - (ql.value + (c * qr.value)).withUnit[UL] + new AddNC((ql: Quantity[Float, UL], qr: Quantity[Float, UR]) => (ql.value + (c*qr.value)).withUnit[UL]) transparent inline given ctx_sub_Float_1U[U]: Sub[Float, U, Float, U] = - new Sub[Float, U, Float, U]: - type VO = Float - type UO = U - def apply(ql: Quantity[Float, U], qr: Quantity[Float, U]): Quantity[Float, U] = - (ql.value - qr.value).withUnit[U] + new SubNC((ql: Quantity[Float, U], qr: Quantity[Float, U]) => (ql.value - qr.value).withUnit[U]) transparent inline given ctx_sub_Float_2U[UL, UR](using Conversion[Quantity[Float, UR], Quantity[Float, UL]] ): Sub[Float, UL, Float, UR] = val c = coefficientFloat[UR, UL] - new Sub[Float, UL, Float, UR]: - type VO = Float - type UO = UL - def apply(ql: Quantity[Float, UL], qr: Quantity[Float, UR]): Quantity[Float, UL] = - (ql.value - (c * qr.value)).withUnit[UL] + new SubNC((ql: Quantity[Float, UL], qr: Quantity[Float, UR]) => (ql.value - (c*qr.value)).withUnit[UL]) transparent inline given ctx_mul_Float_2U[UL, UR](using su: SimplifiedUnit[UL * UR]): Mul[Float, UL, Float, UR] = - new Mul[Float, UL, Float, UR]: - type VO = Float - type UO = su.UO - def apply(ql: Quantity[Float, UL], qr: Quantity[Float, UR]): Quantity[Float, UO] = - (ql.value * qr.value).withUnit[UO] + new MulNC((ql: Quantity[Float, UL], qr: Quantity[Float, UR]) => (ql.value * qr.value).withUnit[su.UO]) transparent inline given ctx_div_Float_2U[UL, UR](using su: SimplifiedUnit[UL / UR]): Div[Float, UL, Float, UR] = - new Div[Float, UL, Float, UR]: - type VO = Float - type UO = su.UO - def apply(ql: Quantity[Float, UL], qr: Quantity[Float, UR]): Quantity[Float, UO] = - (ql.value / qr.value).withUnit[UO] + new DivNC((ql: Quantity[Float, UL], qr: Quantity[Float, UR]) => (ql.value / qr.value).withUnit[su.UO]) diff --git a/core/src/main/scala/coulomb/ops/standard/sub.scala b/core/src/main/scala/coulomb/ops/standard/sub.scala index 8acfb25db..5efeff159 100644 --- a/core/src/main/scala/coulomb/ops/standard/sub.scala +++ b/core/src/main/scala/coulomb/ops/standard/sub.scala @@ -25,13 +25,15 @@ object sub: import coulomb.{Quantity, withUnit} import coulomb.ops.{Sub, ValueResolution} + import infra.SubNC + transparent inline given ctx_sub_1V1U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, equ: UR =:= UL, alg: AdditiveGroup[VL] ): Sub[VL, UL, VR, UR] = - new infra.Sub1V1U[VL, UL, VR, UR](alg, eqv) + new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(ql.value, eqv(qr.value)).withUnit[UL]) transparent inline given ctx_sub_1V2U[VL, UL, VR, UR](using eqv: VR =:= VL, @@ -39,7 +41,7 @@ object sub: icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], alg: AdditiveGroup[VL] ): Sub[VL, UL, VR, UR] = - new infra.Sub1V2U[VL, UL, VR, UR](alg, icr) + new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(ql.value, icr(qr).value).withUnit[UL]) transparent inline given ctx_sub_2V1U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -49,7 +51,7 @@ object sub: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveGroup[vres.VO] ): Sub[VL, UL, VR, UR] = - new infra.Sub2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) transparent inline given ctx_sub_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -59,31 +61,9 @@ object sub: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveGroup[vres.VO] ): Sub[VL, UL, VR, UR] = - new infra.Sub2V2U[VL, UL, VR, UR, vres.VO](alg, icl, icr) + new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) object infra: - class Sub1V1U[VL, UL, VR, UR]( - alg: AdditiveGroup[VL], - eqv: VR =:= VL) extends Sub[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(ql.value, eqv(qr.value)).withUnit[UO] - - class Sub1V2U[VL, UL, VR, UR]( - alg: AdditiveGroup[VL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends Sub[VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(ql.value, icr(qr).value).withUnit[UO] - - class Sub2V2U[VL, UL, VR, UR, VOp]( - alg: AdditiveGroup[VOp], - icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends Sub[VL, UL, VR, UR]: + class SubNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Sub[VL, UL, VR, UR]: type VO = VOp - type UO = UL - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] - + type UO = UOp diff --git a/core/src/main/scala/coulomb/quantity.scala b/core/src/main/scala/coulomb/quantity.scala index 43fe2a577..20aab7dcc 100644 --- a/core/src/main/scala/coulomb/quantity.scala +++ b/core/src/main/scala/coulomb/quantity.scala @@ -103,16 +103,16 @@ object quantity: neg(ql) transparent inline def +[VR, UR](qr: Quantity[VR, UR])(using add: Add[VL, UL, VR, UR]): Quantity[add.VO, add.UO] = - add(ql, qr) + add.eval(ql, qr) transparent inline def -[VR, UR](qr: Quantity[VR, UR])(using sub: Sub[VL, UL, VR, UR]): Quantity[sub.VO, sub.UO] = - sub(ql, qr) + sub.eval(ql, qr) transparent inline def *[VR, UR](qr: Quantity[VR, UR])(using mul: Mul[VL, UL, VR, UR]): Quantity[mul.VO, mul.UO] = - mul(ql, qr) + mul.eval(ql, qr) transparent inline def /[VR, UR](qr: Quantity[VR, UR])(using div: Div[VL, UL, VR, UR]): Quantity[div.VO, div.UO] = - div(ql, qr) + div.eval(ql, qr) transparent inline def tquot[VR, UR](qr: Quantity[VR, UR])(using tq: TQuot[VL, UL, VR, UR]): Quantity[tq.VO, tq.UO] = tq(ql, qr) From a2871f4ab77c9d9e6c4b0f386b5e4949cc149a0d Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Mon, 4 Apr 2022 18:28:20 -0700 Subject: [PATCH 22/35] clean up implicit conversion defs using SAM/lambdas --- .../coulomb/conversion/standard/scala.scala | 38 +++---------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/core/src/main/scala/coulomb/conversion/standard/scala.scala b/core/src/main/scala/coulomb/conversion/standard/scala.scala index c7c0ae822..b4a14727a 100644 --- a/core/src/main/scala/coulomb/conversion/standard/scala.scala +++ b/core/src/main/scala/coulomb/conversion/standard/scala.scala @@ -26,54 +26,26 @@ object scala: // https://docs.scala-lang.org/scala3/reference/contextual/conversions.html given ctx_Quantity_Conversion_1V1U[V, U]: Conversion[Quantity[V, U], Quantity[V, U]] = - new infra.QC1V1U[V, U] + (q: Quantity[V, U]) => q given ctx_Quantity_Conversion_1V2U[V, UF, UT](using uc: UnitConversion[V, UF, UT] ): Conversion[Quantity[V, UF], Quantity[V, UT]] = - new infra.QC1V2U[V, UF, UT](uc) + (q: Quantity[V, UF]) => uc(q.value).withUnit[UT] given ctx_Quantity_Conversion_2V1U[U, VF, VT](using vc: ValueConversion[VF, VT], ): Conversion[Quantity[VF, U], Quantity[VT, U]] = - new infra.QC2V1U[U, VF, VT](vc) + (q: Quantity[VF, U]) => vc(q.value).withUnit[U] given ctx_Quantity_Conversion_2V2U[VF, UF, VT, UT](using vc: ValueConversion[VF, VT], uc: UnitConversion[VT, UF, UT] ): Conversion[Quantity[VF, UF], Quantity[VT, UT]] = - new infra.QC2V2U[VF, UF, VT, UT](vc, uc) + (q: Quantity[VF, UF]) => uc(vc(q.value)).withUnit[UT] given ctx_DeltaQuantity_conversion_2V2U[B, VF, UF, VT, UT](using vc: ValueConversion[VF, VT], uc: DeltaUnitConversion[VT, B, UF, UT] ): Conversion[DeltaQuantity[VF, UF, B], DeltaQuantity[VT, UT, B]] = - new infra.DQC2V2U[B, VF, UF, VT, UT](vc, uc) - - object infra: - class QC1V1U[V, U] extends Conversion[Quantity[V, U], Quantity[V, U]]: - def apply(q: Quantity[V, U]): Quantity[V, U] = q - - class QC1V2U[V, UF, UT](uc: UnitConversion[V, UF, UT]) extends - Conversion[Quantity[V, UF], Quantity[V, UT]]: - def apply(q: Quantity[V, UF]): Quantity[V, UT] = - uc(q.value).withUnit[UT] - - class QC2V1U[U, VF, VT](vc: ValueConversion[VF, VT]) extends - Conversion[Quantity[VF, U], Quantity[VT, U]]: - def apply(q: Quantity[VF, U]): Quantity[VT, U] = - vc(q.value).withUnit[U] - - class QC2V2U[VF, UF, VT, UT]( - vc: ValueConversion[VF, VT], - uc: UnitConversion[VT, UF, UT]) extends - Conversion[Quantity[VF, UF], Quantity[VT, UT]]: - def apply(q: Quantity[VF, UF]): Quantity[VT, UT] = - uc(vc(q.value)).withUnit[UT] - - class DQC2V2U[B, VF, UF, VT, UT]( - vc: ValueConversion[VF, VT], - uc: DeltaUnitConversion[VT, B, UF, UT]) extends - Conversion[DeltaQuantity[VF, UF, B], DeltaQuantity[VT, UT, B]]: - def apply(q: DeltaQuantity[VF, UF, B]): DeltaQuantity[VT, UT, B] = - uc(vc(q.value)).withDeltaUnit[UT, B] + (q: DeltaQuantity[VF, UF, B]) => uc(vc(q.value)).withDeltaUnit[UT, B] From c2d3615adc82afd715796b317a039806f5fc571b Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Mon, 4 Apr 2022 18:29:38 -0700 Subject: [PATCH 23/35] increase benchmark iteration time for more stability --- benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala b/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala index 304add441..5b1909811 100644 --- a/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala +++ b/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala @@ -24,8 +24,8 @@ import org.openjdk.jmh.annotations.* @Fork(1) @BenchmarkMode(Array(Mode.Throughput)) @OutputTimeUnit(TimeUnit.MILLISECONDS) -@Warmup(iterations = 3, time = 1) -@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 3, time = 2) +@Measurement(iterations = 10, time = 2) class QuantityBenchmark: import scala.language.implicitConversions import coulomb.* From 817be07d4d37db09f8b0c81e2d49e0b355b5ce77 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Mon, 4 Apr 2022 18:30:11 -0700 Subject: [PATCH 24/35] experiment with named class for unit defs --- core/src/main/scala/coulomb/define/define.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/scala/coulomb/define/define.scala b/core/src/main/scala/coulomb/define/define.scala index 99995a1aa..d7cb6a5b8 100644 --- a/core/src/main/scala/coulomb/define/define.scala +++ b/core/src/main/scala/coulomb/define/define.scala @@ -36,6 +36,11 @@ abstract class BaseUnit[U, Name, Abbv] extends NamedUnit[Name, Abbv] * @tparam Abbv unit abbreviation */ abstract class DerivedUnit[U, D, Name, Abbv] extends NamedUnit[Name, Abbv] +object DerivedUnit: + given ctx_unit_to_DU[U, D, Name, Abbv]: scala.Conversion[Unit, DerivedUnit[U, D, Name, Abbv]] = + (_: Unit) => new infra.DU[U, D, Name, Abbv] + object infra: + class DU[U, D, Name, Abbv] extends DerivedUnit[U, D, Name, Abbv] /** * Delta Units represent units with an offset in their transforms, for example temperatures or times @@ -47,3 +52,4 @@ abstract class DerivedUnit[U, D, Name, Abbv] extends NamedUnit[Name, Abbv] * @tparam Abbv unit abbreviation */ abstract class DeltaUnit[U, D, O, Name, Abbv] extends DerivedUnit[U, D, Name, Abbv] + From e93247dd36a4bf991a4481c4c48abfc645857d51 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Mon, 4 Apr 2022 19:14:00 -0700 Subject: [PATCH 25/35] neg with SAM/lambda --- core/src/main/scala/coulomb/ops/ops.scala | 3 +-- core/src/main/scala/coulomb/ops/standard/neg.scala | 9 ++------- .../coulomb/ops/standard/optimizations/double.scala | 5 ++--- .../scala/coulomb/ops/standard/optimizations/float.scala | 5 ++--- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 5174d03a1..667dc4ffc 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -21,8 +21,7 @@ import scala.annotation.implicitNotFound import coulomb.* @implicitNotFound("Negation not defined in scope for Quantity[${V}, ${U}]") -abstract class Neg[V, U]: - def apply(q: Quantity[V, U]): Quantity[V, U] +abstract class Neg[V, U] extends (Quantity[V, U] => Quantity[V, U]) @implicitNotFound("Addition not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class Add[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/neg.scala b/core/src/main/scala/coulomb/ops/standard/neg.scala index 3d9cdbd5a..72c3d30de 100644 --- a/core/src/main/scala/coulomb/ops/standard/neg.scala +++ b/core/src/main/scala/coulomb/ops/standard/neg.scala @@ -22,10 +22,5 @@ object neg: import coulomb.{Quantity, withUnit} import coulomb.ops.Neg - inline given ctx_quantity_neg[V, U](using alg: AdditiveGroup[V]): Neg[V, U] = - new infra.NegNC[V, U](alg) - - object infra: - class NegNC[V, U](alg: AdditiveGroup[V]) extends Neg[V, U]: - def apply(q: Quantity[V, U]): Quantity[V, U] = - alg.negate(q.value).withUnit[U] + given ctx_quantity_neg[V, U](using alg: AdditiveGroup[V]): Neg[V, U] = + (q: Quantity[V, U]) => alg.negate(q.value).withUnit[U] diff --git a/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala b/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala index 52cf44236..8f4a0aced 100644 --- a/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala +++ b/core/src/main/scala/coulomb/ops/standard/optimizations/double.scala @@ -26,9 +26,8 @@ import coulomb.ops.standard.named.* import coulomb.conversion.coefficients.* object double: - inline given ctx_quantity_neg_Double[U]: Neg[Double, U] = - new Neg[Double, U]: - def apply(q: Quantity[Double, U]): Quantity[Double, U] = (-(q.value)).withUnit[U] + given ctx_quantity_neg_Double[U]: Neg[Double, U] = + (q: Quantity[Double, U]) => (-(q.value)).withUnit[U] transparent inline given ctx_add_Double_1U[U]: Add[Double, U, Double, U] = new AddNC((ql: Quantity[Double, U], qr: Quantity[Double, U]) => (ql.value + qr.value).withUnit[U]) diff --git a/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala b/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala index eda699154..75d88020e 100644 --- a/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala +++ b/core/src/main/scala/coulomb/ops/standard/optimizations/float.scala @@ -26,9 +26,8 @@ import coulomb.ops.standard.named.* import coulomb.conversion.coefficients.* object float: - inline given ctx_quantity_neg_Float[U]: Neg[Float, U] = - new Neg[Float, U]: - def apply(q: Quantity[Float, U]): Quantity[Float, U] = (-(q.value)).withUnit[U] + given ctx_quantity_neg_Float[U]: Neg[Float, U] = + (q: Quantity[Float, U]) => (-(q.value)).withUnit[U] transparent inline given ctx_add_Float_1U[U]: Add[Float, U, Float, U] = new AddNC((ql: Quantity[Float, U], qr: Quantity[Float, U]) => (ql.value + qr.value).withUnit[U]) From ee70e03f164ff1a72cf8e80354a91c2b5f97055f Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 10:25:53 -0700 Subject: [PATCH 26/35] TQuotNC --- core/src/main/scala/coulomb/ops/ops.scala | 2 +- .../main/scala/coulomb/ops/standard/add.scala | 10 ++++----- .../main/scala/coulomb/ops/standard/div.scala | 6 ++---- .../main/scala/coulomb/ops/standard/mul.scala | 6 ++---- .../scala/coulomb/ops/standard/named.scala | 1 + .../main/scala/coulomb/ops/standard/sub.scala | 10 ++++----- .../scala/coulomb/ops/standard/tquot.scala | 21 ++++--------------- core/src/main/scala/coulomb/quantity.scala | 2 +- 8 files changed, 19 insertions(+), 39 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 667dc4ffc..71d10d82f 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -51,7 +51,7 @@ abstract class Div[VL, UL, VR, UR]: abstract class TQuot[VL, UL, VR, UR]: type VO type UO - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] + val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VO, UO] @implicitNotFound("Power not defined in scope for Quantity[${V}, ${U}] ^ ${P}") abstract class Pow[V, U, P]: diff --git a/core/src/main/scala/coulomb/ops/standard/add.scala b/core/src/main/scala/coulomb/ops/standard/add.scala index 8ebf4ad64..ad2bc9942 100644 --- a/core/src/main/scala/coulomb/ops/standard/add.scala +++ b/core/src/main/scala/coulomb/ops/standard/add.scala @@ -25,15 +25,13 @@ object add: import coulomb.{Quantity, withUnit} import coulomb.ops.{Add, ValueResolution} - import infra.AddNC - transparent inline given ctx_add_1V1U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, equ: UR =:= UL, alg: AdditiveSemigroup[VL] ): Add[VL, UL, VR, UR] = - new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(ql.value, eqv(qr.value)).withUnit[UL]) + new infra.AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(ql.value, eqv(qr.value)).withUnit[UL]) transparent inline given ctx_add_1V2U[VL, UL, VR, UR](using eqv: VR =:= VL, @@ -41,7 +39,7 @@ object add: icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], alg: AdditiveSemigroup[VL] ): Add[VL, UL, VR, UR] = - new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(ql.value, icr(qr).value).withUnit[UL]) + new infra.AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(ql.value, icr(qr).value).withUnit[UL]) transparent inline given ctx_add_2V1U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -51,7 +49,7 @@ object add: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveSemigroup[vres.VO] ): Add[VL, UL, VR, UR] = - new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) + new infra.AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) transparent inline given ctx_add_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -61,7 +59,7 @@ object add: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveSemigroup[vres.VO] ): Add[VL, UL, VR, UR] = - new AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) + new infra.AddNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withUnit[UL]) object infra: class AddNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Add[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/div.scala b/core/src/main/scala/coulomb/ops/standard/div.scala index 24d476ce3..b05491ac4 100644 --- a/core/src/main/scala/coulomb/ops/standard/div.scala +++ b/core/src/main/scala/coulomb/ops/standard/div.scala @@ -25,15 +25,13 @@ object div: import coulomb.{`/`, Quantity, withUnit} import coulomb.ops.{Div, SimplifiedUnit, ValueResolution} - import infra.DivNC - transparent inline given ctx_div_1V2U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, alg: MultiplicativeGroup[VL], su: SimplifiedUnit[UL / UR] ): Div[VL, UL, VR, UR] = - new DivNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.div(ql.value, eqv(qr.value)).withUnit[su.UO]) + new infra.DivNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.div(ql.value, eqv(qr.value)).withUnit[su.UO]) transparent inline given ctx_div_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -43,7 +41,7 @@ object div: alg: MultiplicativeGroup[vres.VO], su: SimplifiedUnit[UL / UR] ): Div[VL, UL, VR, UR] = - new DivNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.div(icl(ql).value, icr(qr).value).withUnit[su.UO]) + new infra.DivNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.div(icl(ql).value, icr(qr).value).withUnit[su.UO]) object infra: class DivNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Div[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/mul.scala b/core/src/main/scala/coulomb/ops/standard/mul.scala index 2db807101..9dfc631d6 100644 --- a/core/src/main/scala/coulomb/ops/standard/mul.scala +++ b/core/src/main/scala/coulomb/ops/standard/mul.scala @@ -25,15 +25,13 @@ object mul: import coulomb.{`*`, Quantity, withUnit} import coulomb.ops.{Mul, SimplifiedUnit, ValueResolution} - import infra.MulNC - transparent inline given ctx_mul_1V2U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, alg: MultiplicativeSemigroup[VL], su: SimplifiedUnit[UL * UR] ): Mul[VL, UL, VR, UR] = - new MulNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.times(ql.value, eqv(qr.value)).withUnit[su.UO]) + new infra.MulNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.times(ql.value, eqv(qr.value)).withUnit[su.UO]) transparent inline given ctx_mul_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -43,7 +41,7 @@ object mul: alg: MultiplicativeSemigroup[vres.VO], su: SimplifiedUnit[UL * UR] ): Mul[VL, UL, VR, UR] = - new MulNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.times(icl(ql).value, icr(qr).value).withUnit[su.UO]) + new infra.MulNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.times(icl(ql).value, icr(qr).value).withUnit[su.UO]) object infra: class MulNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Mul[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/named.scala b/core/src/main/scala/coulomb/ops/standard/named.scala index 286a925dd..6d418fce9 100644 --- a/core/src/main/scala/coulomb/ops/standard/named.scala +++ b/core/src/main/scala/coulomb/ops/standard/named.scala @@ -21,4 +21,5 @@ object named: export sub.infra.SubNC export mul.infra.MulNC export div.infra.DivNC + export tquot.infra.TQuotNC diff --git a/core/src/main/scala/coulomb/ops/standard/sub.scala b/core/src/main/scala/coulomb/ops/standard/sub.scala index 5efeff159..8d54dedc9 100644 --- a/core/src/main/scala/coulomb/ops/standard/sub.scala +++ b/core/src/main/scala/coulomb/ops/standard/sub.scala @@ -25,15 +25,13 @@ object sub: import coulomb.{Quantity, withUnit} import coulomb.ops.{Sub, ValueResolution} - import infra.SubNC - transparent inline given ctx_sub_1V1U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, equ: UR =:= UL, alg: AdditiveGroup[VL] ): Sub[VL, UL, VR, UR] = - new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(ql.value, eqv(qr.value)).withUnit[UL]) + new infra.SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(ql.value, eqv(qr.value)).withUnit[UL]) transparent inline given ctx_sub_1V2U[VL, UL, VR, UR](using eqv: VR =:= VL, @@ -41,7 +39,7 @@ object sub: icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], alg: AdditiveGroup[VL] ): Sub[VL, UL, VR, UR] = - new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(ql.value, icr(qr).value).withUnit[UL]) + new infra.SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(ql.value, icr(qr).value).withUnit[UL]) transparent inline given ctx_sub_2V1U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -51,7 +49,7 @@ object sub: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveGroup[vres.VO] ): Sub[VL, UL, VR, UR] = - new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) + new infra.SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) transparent inline given ctx_sub_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -61,7 +59,7 @@ object sub: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveGroup[vres.VO] ): Sub[VL, UL, VR, UR] = - new SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) + new infra.SubNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) object infra: class SubNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends Sub[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/tquot.scala b/core/src/main/scala/coulomb/ops/standard/tquot.scala index 816d637f4..5142f435a 100644 --- a/core/src/main/scala/coulomb/ops/standard/tquot.scala +++ b/core/src/main/scala/coulomb/ops/standard/tquot.scala @@ -31,7 +31,7 @@ object tquot: alg: TruncatedDivision[VL], su: SimplifiedUnit[UL / UR] ): TQuot[VL, UL, VR, UR] = - new infra.TQuot1V2U[VL, UL, VR, UR, su.UO](alg, eqv) + new infra.TQuotNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.tquot(ql.value, eqv(qr.value)).withUnit[su.UO]) transparent inline given ctx_tquot_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -41,22 +41,9 @@ object tquot: alg: TruncatedDivision[vres.VO], su: SimplifiedUnit[UL / UR] ): TQuot[VL, UL, VR, UR] = - new infra.TQuot2V2U[VL, UL, VR, UR, vres.VO, su.UO](alg, icl, icr) + new infra.TQuotNC((ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => alg.tquot(icl(ql).value, icr(qr).value).withUnit[su.UO]) object infra: - class TQuot1V2U[VL, UL, VR, UR, UOp]( - alg: TruncatedDivision[VL], - eqv: VR =:= VL) extends TQuot[VL, UL, VR, UR]: - type VO = VL - type UO = UOp - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.tquot(ql.value, eqv(qr.value)).withUnit[UO] - - class TQuot2V2U[VL, UL, VR, UR, VOp, UOp]( - alg: TruncatedDivision[VOp], - icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UR]]) extends TQuot[VL, UL, VR, UR]: + class TQuotNC[VL, UL, VR, UR, VOp, UOp](val eval: (Quantity[VL, UL], Quantity[VR, UR]) => Quantity[VOp, UOp]) extends TQuot[VL, UL, VR, UR]: type VO = VOp - type UO = UOp - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Quantity[VO, UO] = - alg.tquot(icl(ql).value, icr(qr).value).withUnit[UO] + type UO = UOp diff --git a/core/src/main/scala/coulomb/quantity.scala b/core/src/main/scala/coulomb/quantity.scala index 20aab7dcc..0719e7e8b 100644 --- a/core/src/main/scala/coulomb/quantity.scala +++ b/core/src/main/scala/coulomb/quantity.scala @@ -115,7 +115,7 @@ object quantity: div.eval(ql, qr) transparent inline def tquot[VR, UR](qr: Quantity[VR, UR])(using tq: TQuot[VL, UL, VR, UR]): Quantity[tq.VO, tq.UO] = - tq(ql, qr) + tq.eval(ql, qr) transparent inline def pow[P](using pow: Pow[VL, UL, P]): Quantity[pow.VO, pow.UO] = pow(ql) From 92c63fad85ed7ea4ca19277c17389045e679efa6 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 12:46:48 -0700 Subject: [PATCH 27/35] PowNC, TPowNC --- core/src/main/scala/coulomb/ops/ops.scala | 4 +-- .../scala/coulomb/ops/standard/named.scala | 2 ++ .../main/scala/coulomb/ops/standard/pow.scala | 27 ++++++------------- .../scala/coulomb/ops/standard/tpow.scala | 9 +++---- core/src/main/scala/coulomb/quantity.scala | 4 +-- 5 files changed, 18 insertions(+), 28 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 71d10d82f..6d9bb80ad 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -57,13 +57,13 @@ abstract class TQuot[VL, UL, VR, UR]: abstract class Pow[V, U, P]: type VO type UO - def apply(q: Quantity[V, U]): Quantity[VO, UO] + val eval: Quantity[V, U] => Quantity[VO, UO] @implicitNotFound("Truncating Power not defined in scope for Quantity[${V}, ${U}] ^ ${P}") abstract class TPow[V, U, P]: type VO type UO - def apply(q: Quantity[V, U]): Quantity[VO, UO] + val eval: Quantity[V, U] => Quantity[VO, UO] @implicitNotFound("Ordering not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class Ord[VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/named.scala b/core/src/main/scala/coulomb/ops/standard/named.scala index 6d418fce9..1c75e48a6 100644 --- a/core/src/main/scala/coulomb/ops/standard/named.scala +++ b/core/src/main/scala/coulomb/ops/standard/named.scala @@ -22,4 +22,6 @@ object named: export mul.infra.MulNC export div.infra.DivNC export tquot.infra.TQuotNC + export pow.infra.PowNC + export tpow.infra.TPowNC diff --git a/core/src/main/scala/coulomb/ops/standard/pow.scala b/core/src/main/scala/coulomb/ops/standard/pow.scala index f544983e5..e71213403 100644 --- a/core/src/main/scala/coulomb/ops/standard/pow.scala +++ b/core/src/main/scala/coulomb/ops/standard/pow.scala @@ -31,7 +31,8 @@ object pow: alg: FractionalPower[V], su: SimplifiedUnit[U ^ E] ): Pow[V, U, E] = - new infra.PowFP[V, U, E, su.UO](alg, typeexpr.double[E]) + val e = typeexpr.double[E] + new infra.PowNC[V, U, E, V, su.UO]((q: Quantity[V, U]) => alg.pow(q.value, e).withUnit[su.UO]) transparent inline given ctx_pow_MultiplicativeGroup[V, U, E](using nfp: NotGiven[FractionalPower[V]], @@ -39,7 +40,8 @@ object pow: aie: typeexpr.AllInt[E], su: SimplifiedUnit[U ^ E] ): Pow[V, U, E] = - new infra.PowMG[V, U, E, su.UO](alg, aie.value) + val e = aie.value + new infra.PowNC[V, U, E, V, su.UO]((q: Quantity[V, U]) => alg.pow(q.value, e).withUnit[su.UO]) transparent inline given ctx_pow_MultiplicativeSemigroup[V, U, E](using nfp: NotGiven[FractionalPower[V]], @@ -48,23 +50,10 @@ object pow: pie: typeexpr.PosInt[E], su: SimplifiedUnit[U ^ E] ): Pow[V, U, E] = - new infra.PowMSG[V, U, E, su.UO](alg, pie.value) + val e = pie.value + new infra.PowNC[V, U, E, V, su.UO]((q: Quantity[V, U]) => alg.pow(q.value, e).withUnit[su.UO]) object infra: - class PowFP[V, U, E, UOp](alg: FractionalPower[V], e: Double) extends Pow[V, U, E]: - type VO = V + class PowNC[V, U, E, VOp, UOp](val eval: Quantity[V, U] => Quantity[VOp, UOp]) extends Pow[V, U, E]: + type VO = VOp type UO = UOp - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] - - class PowMG[V, U, E, UOp](alg: MultiplicativeGroup[V], e: Int) extends Pow[V, U, E]: - type VO = V - type UO = UOp - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] - - class PowMSG[V, U, E, UOp](alg: MultiplicativeSemigroup[V], e: Int) extends Pow[V, U, E]: - type VO = V - type UO = UOp - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.pow(q.value, e).withUnit[UO] diff --git a/core/src/main/scala/coulomb/ops/standard/tpow.scala b/core/src/main/scala/coulomb/ops/standard/tpow.scala index 5730f761e..b8a9e3861 100644 --- a/core/src/main/scala/coulomb/ops/standard/tpow.scala +++ b/core/src/main/scala/coulomb/ops/standard/tpow.scala @@ -28,11 +28,10 @@ object tpow: alg: TruncatingPower[V], su: SimplifiedUnit[U ^ E] ): TPow[V, U, E] = - new infra.TPowNC[V, U, E, su.UO](alg, typeexpr.double[E]) + val e = typeexpr.double[E] + new infra.TPowNC[V, U, E, V, su.UO]((q: Quantity[V, U]) => alg.tpow(q.value, e).withUnit[su.UO]) object infra: - class TPowNC[V, U, E, UOp](alg: TruncatingPower[V], e: Double) extends TPow[V, U, E]: - type VO = V + class TPowNC[V, U, E, VOp, UOp](val eval: Quantity[V, U] => Quantity[VOp, UOp]) extends TPow[V, U, E]: + type VO = VOp type UO = UOp - def apply(q: Quantity[V, U]): Quantity[VO, UO] = - alg.tpow(q.value, e).withUnit[UO] diff --git a/core/src/main/scala/coulomb/quantity.scala b/core/src/main/scala/coulomb/quantity.scala index 0719e7e8b..25cc3dc0f 100644 --- a/core/src/main/scala/coulomb/quantity.scala +++ b/core/src/main/scala/coulomb/quantity.scala @@ -118,10 +118,10 @@ object quantity: tq.eval(ql, qr) transparent inline def pow[P](using pow: Pow[VL, UL, P]): Quantity[pow.VO, pow.UO] = - pow(ql) + pow.eval(ql) transparent inline def tpow[P](using tp: TPow[VL, UL, P]): Quantity[tp.VO, tp.UO] = - tp(ql) + tp.eval(ql) inline def ===[VR, UR](qr: Quantity[VR, UR])(using ord: Ord[VL, UL, VR, UR]): Boolean = ord(ql, qr) == 0 From 72795b8b1b97d9578541e6e5626b7f7139002838 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 14:48:02 -0700 Subject: [PATCH 28/35] Ord using SAM/lambda --- core/src/main/scala/coulomb/ops/ops.scala | 3 +- .../main/scala/coulomb/ops/standard/ord.scala | 36 +++++-------------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 6d9bb80ad..747b658d3 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -66,8 +66,7 @@ abstract class TPow[V, U, P]: val eval: Quantity[V, U] => Quantity[VO, UO] @implicitNotFound("Ordering not defined in scope for Quantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") -abstract class Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int +abstract class Ord[VL, UL, VR, UR] extends ((Quantity[VL, UL], Quantity[VR, UR]) => Int) @implicitNotFound("Subtraction not defined in scope for DeltaQuantity[${VL}, ${UL}] and DeltaQuantity[${VR}, ${UR}]") abstract class DeltaSub[B, VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/ord.scala b/core/src/main/scala/coulomb/ops/standard/ord.scala index 79f90c462..2edc0f529 100644 --- a/core/src/main/scala/coulomb/ops/standard/ord.scala +++ b/core/src/main/scala/coulomb/ops/standard/ord.scala @@ -25,23 +25,23 @@ object ord: import coulomb.Quantity import coulomb.ops.{Ord, ValueResolution} - transparent inline given ctx_ord_1V1U[VL, UL, VR, UR](using + given ctx_ord_1V1U[VL, UL, VR, UR](using // https://github.com/lampepfl/dotty/issues/14585 eqv: VR =:= VL, equ: UR =:= UL, ord: Order[VL] ): Ord[VL, UL, VR, UR] = - new infra.Ord1V1U[VL, UL, VR, UR](ord, eqv) + (ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => ord.compare(ql.value, eqv(qr.value)) - transparent inline given ctx_ord_1V2U[VL, UL, VR, UR](using + given ctx_ord_1V2U[VL, UL, VR, UR](using eqv: VR =:= VL, neu: NotGiven[UR =:= UL], icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], ord: Order[VL] ): Ord[VL, UL, VR, UR] = - new infra.Ord1V2U[VL, UL, VR, UR](ord, icr) + (ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => ord.compare(ql.value, icr(qr).value) - transparent inline given ctx_ord_2V1U[VL, UL, VR, UR](using + given ctx_ord_2V1U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], equ: UR =:= UL, vres: ValueResolution[VL, VR], @@ -49,9 +49,9 @@ object ord: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], ord: Order[vres.VO] ): Ord[VL, UL, VR, UR] = - new infra.Ord2V2U[VL, UL, VR, UR, vres.VO](ord, icl, icr) + (ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => ord.compare(icl(ql).value, icr(qr).value) - transparent inline given ctx_ord_2V2U[VL, UL, VR, UR](using + given ctx_ord_2V2U[VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], neu: NotGiven[UR =:= UL], vres: ValueResolution[VL, VR], @@ -59,24 +59,4 @@ object ord: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], ord: Order[vres.VO] ): Ord[VL, UL, VR, UR] = - new infra.Ord2V2U[VL, UL, VR, UR, vres.VO](ord, icl, icr) - - object infra: - class Ord1V1U[VL, UL, VR, UR]( - ord: Order[VL], - eqv: VR =:= VL) extends Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(ql.value, eqv(qr.value)) - - class Ord1V2U[VL, UL, VR, UR]( - ord: Order[VL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(ql.value, icr(qr).value) - - class Ord2V2U[VL, UL, VR, UR, VOp]( - ord: Order[VOp], - icl: Conversion[Quantity[VL, UL], Quantity[VOp, UL]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends Ord[VL, UL, VR, UR]: - def apply(ql: Quantity[VL, UL], qr: Quantity[VR, UR]): Int = - ord.compare(icl(ql).value, icr(qr).value) + (ql: Quantity[VL, UL], qr: Quantity[VR, UR]) => ord.compare(icl(ql).value, icr(qr).value) From cbcd64ab9452da80d2a4f766c7917f05de8fd781 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 15:04:03 -0700 Subject: [PATCH 29/35] DeltaSubNC --- .../main/scala/coulomb/deltaquantity.scala | 2 +- core/src/main/scala/coulomb/ops/ops.scala | 2 +- .../scala/coulomb/ops/standard/deltasub.scala | 34 ++++--------------- .../scala/coulomb/ops/standard/named.scala | 1 + 4 files changed, 9 insertions(+), 30 deletions(-) diff --git a/core/src/main/scala/coulomb/deltaquantity.scala b/core/src/main/scala/coulomb/deltaquantity.scala index 63a03bbbd..2a75e6531 100644 --- a/core/src/main/scala/coulomb/deltaquantity.scala +++ b/core/src/main/scala/coulomb/deltaquantity.scala @@ -77,7 +77,7 @@ object deltaquantity: conv(ql.value).withDeltaUnit[U, B] transparent inline def -[VR, UR](qr: DeltaQuantity[VR, UR, B])(using sub: DeltaSub[B, VL, UL, VR, UR]): Quantity[sub.VO, sub.UO] = - sub(ql, qr) + sub.eval(ql, qr) transparent inline def -[VR, UR](qr: Quantity[VR, UR])(using sub: DeltaSubQ[B, VL, UL, VR, UR]): DeltaQuantity[sub.VO, sub.UO, B] = sub(ql, qr) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 747b658d3..62eec49ba 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -72,7 +72,7 @@ abstract class Ord[VL, UL, VR, UR] extends ((Quantity[VL, UL], Quantity[VR, UR]) abstract class DeltaSub[B, VL, UL, VR, UR]: type VO type UO - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] + val eval: (DeltaQuantity[VL, UL, B], DeltaQuantity[VR, UR, B]) => Quantity[VO, UO] @implicitNotFound("Subtraction not defined in scope for DeltaQuantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class DeltaSubQ[B, VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/deltasub.scala b/core/src/main/scala/coulomb/ops/standard/deltasub.scala index ca30ddab3..082dd2b9e 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltasub.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltasub.scala @@ -30,7 +30,7 @@ object deltasub: equ: UR =:= UL, alg: AdditiveGroup[VL] ): DeltaSub[B, VL, UL, VR, UR] = - new infra.DeltaSub1V1U[B, VL, UL, VR, UR](alg, eqv) + new infra.DeltaSubNC((ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => alg.minus(ql.value, eqv(qr.value)).withUnit[UL]) transparent inline given ctx_deltasub_1V2U[B, VL, UL, VR, UR](using eqv: VR =:= VL, @@ -38,7 +38,7 @@ object deltasub: icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]], alg: AdditiveGroup[VL] ): DeltaSub[B, VL, UL, VR, UR] = - new infra.DeltaSub1V2U[B, VL, UL, VR, UR](alg, icr) + new infra.DeltaSubNC((ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => alg.minus(ql.value, icr(qr).value).withUnit[UL]) transparent inline given ctx_deltasub_2V1U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -48,7 +48,7 @@ object deltasub: icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], alg: AdditiveGroup[vres.VO] ): DeltaSub[B, VL, UL, VR, UR] = - new infra.DeltaSub2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + new infra.DeltaSubNC((ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) transparent inline given ctx_deltasub_2V2U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -58,31 +58,9 @@ object deltasub: icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], alg: AdditiveGroup[vres.VO] ): DeltaSub[B, VL, UL, VR, UR] = - new infra.DeltaSub2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + new infra.DeltaSubNC((ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => alg.minus(icl(ql).value, icr(qr).value).withUnit[UL]) object infra: - class DeltaSub1V1U[B, VL, UL, VR, UR]( - alg: AdditiveGroup[VL], - eqv: VR =:= VL) extends DeltaSub[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(ql.value, eqv(qr.value)).withUnit[UO] - - class DeltaSub1V2U[B, VL, UL, VR, UR]( - alg: AdditiveGroup[VL], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]]) extends DeltaSub[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(ql.value, icr(qr).value).withUnit[UO] - - class DeltaSub2V2U[B, VL, UL, VR, UR, VOp]( - alg: AdditiveGroup[VOp], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VOp, UL, B]]) extends DeltaSub[B, VL, UL, VR, UR]: + class DeltaSubNC[B, VL, UL, VR, UR, VOp, UOp](val eval: (DeltaQuantity[VL, UL, B], DeltaQuantity[VR, UR, B]) => Quantity[VOp, UOp]) extends DeltaSub[B, VL, UL, VR, UR]: type VO = VOp - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Quantity[VO, UO] = - alg.minus(icl(ql).value, icr(qr).value).withUnit[UO] - + type UO = UOp diff --git a/core/src/main/scala/coulomb/ops/standard/named.scala b/core/src/main/scala/coulomb/ops/standard/named.scala index 1c75e48a6..329952da5 100644 --- a/core/src/main/scala/coulomb/ops/standard/named.scala +++ b/core/src/main/scala/coulomb/ops/standard/named.scala @@ -24,4 +24,5 @@ object named: export tquot.infra.TQuotNC export pow.infra.PowNC export tpow.infra.TPowNC + export deltasub.infra.DeltaSubNC From 463e3bcc8d944fe3f23f2198cca025ced8cf9eef Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 15:13:57 -0700 Subject: [PATCH 30/35] DeltaSubQNC --- .../main/scala/coulomb/deltaquantity.scala | 2 +- core/src/main/scala/coulomb/ops/ops.scala | 2 +- .../coulomb/ops/standard/deltasubq.scala | 34 ++++--------------- .../scala/coulomb/ops/standard/named.scala | 1 + 4 files changed, 9 insertions(+), 30 deletions(-) diff --git a/core/src/main/scala/coulomb/deltaquantity.scala b/core/src/main/scala/coulomb/deltaquantity.scala index 2a75e6531..344ab6b3e 100644 --- a/core/src/main/scala/coulomb/deltaquantity.scala +++ b/core/src/main/scala/coulomb/deltaquantity.scala @@ -80,7 +80,7 @@ object deltaquantity: sub.eval(ql, qr) transparent inline def -[VR, UR](qr: Quantity[VR, UR])(using sub: DeltaSubQ[B, VL, UL, VR, UR]): DeltaQuantity[sub.VO, sub.UO, B] = - sub(ql, qr) + sub.eval(ql, qr) transparent inline def +[VR, UR](qr: Quantity[VR, UR])(using add: DeltaAddQ[B, VL, UL, VR, UR]): DeltaQuantity[add.VO, add.UO, B] = add(ql, qr) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 62eec49ba..0d220e545 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -78,7 +78,7 @@ abstract class DeltaSub[B, VL, UL, VR, UR]: abstract class DeltaSubQ[B, VL, UL, VR, UR]: type VO type UO - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] + val eval: (DeltaQuantity[VL, UL, B], Quantity[VR, UR]) => DeltaQuantity[VO, UO, B] @implicitNotFound("Addition not defined in scope for DeltaQuantity[${VL}, ${UL}] and Quantity[${VR}, ${UR}]") abstract class DeltaAddQ[B, VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/deltasubq.scala b/core/src/main/scala/coulomb/ops/standard/deltasubq.scala index 111e7b9df..1e5280be4 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltasubq.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltasubq.scala @@ -30,7 +30,7 @@ object deltasubq: equ: UR =:= UL, alg: AdditiveGroup[VL] ): DeltaSubQ[B, VL, UL, VR, UR] = - new infra.DeltaSubQ1V1U[B, VL, UL, VR, UR](alg, eqv) + new infra.DeltaSubQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.minus(ql.value, eqv(qr.value)).withDeltaUnit[UL, B]) transparent inline given ctx_deltasubq_1V2U[B, VL, UL, VR, UR](using eqv: VR =:= VL, @@ -38,7 +38,7 @@ object deltasubq: icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], alg: AdditiveGroup[VL] ): DeltaSubQ[B, VL, UL, VR, UR] = - new infra.DeltaSubQ1V2U[B, VL, UL, VR, UR](alg, icr) + new infra.DeltaSubQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.minus(ql.value, icr(qr).value).withDeltaUnit[UL, B]) transparent inline given ctx_deltasubq_2V1U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -48,7 +48,7 @@ object deltasubq: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveGroup[vres.VO] ): DeltaSubQ[B, VL, UL, VR, UR] = - new infra.DeltaSubQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + new infra.DeltaSubQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withDeltaUnit[UL, B]) transparent inline given ctx_deltasubq_2V2U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -58,31 +58,9 @@ object deltasubq: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveGroup[vres.VO] ): DeltaSubQ[B, VL, UL, VR, UR] = - new infra.DeltaSubQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + new infra.DeltaSubQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.minus(icl(ql).value, icr(qr).value).withDeltaUnit[UL, B]) object infra: - class DeltaSubQ1V1U[B, VL, UL, VR, UR]( - alg: AdditiveGroup[VL], - eqv: VR =:= VL) extends DeltaSubQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(ql.value, eqv(qr.value)).withDeltaUnit[UO, B] - - class DeltaSubQ1V2U[B, VL, UL, VR, UR]( - alg: AdditiveGroup[VL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends DeltaSubQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(ql.value, icr(qr).value).withDeltaUnit[UO, B] - - class DeltaSubQ2V2U[B, VL, UL, VR, UR, VOp]( - alg: AdditiveGroup[VOp], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends DeltaSubQ[B, VL, UL, VR, UR]: + class DeltaSubQNC[B, VL, UL, VR, UR, VOp, UOp](val eval: (DeltaQuantity[VL, UL, B], Quantity[VR, UR]) => DeltaQuantity[VOp, UOp, B]) extends DeltaSubQ[B, VL, UL, VR, UR]: type VO = VOp - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.minus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] - + type UO = UOp diff --git a/core/src/main/scala/coulomb/ops/standard/named.scala b/core/src/main/scala/coulomb/ops/standard/named.scala index 329952da5..af29e9af8 100644 --- a/core/src/main/scala/coulomb/ops/standard/named.scala +++ b/core/src/main/scala/coulomb/ops/standard/named.scala @@ -25,4 +25,5 @@ object named: export pow.infra.PowNC export tpow.infra.TPowNC export deltasub.infra.DeltaSubNC + export deltasubq.infra.DeltaSubQNC From b189c48f9bc37ee6880b15265b7de7e6e3b1cfd2 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 15:40:05 -0700 Subject: [PATCH 31/35] DeltaAddQNC --- .../main/scala/coulomb/deltaquantity.scala | 2 +- core/src/main/scala/coulomb/ops/ops.scala | 2 +- .../coulomb/ops/standard/deltaaddq.scala | 33 ++++--------------- .../scala/coulomb/ops/standard/named.scala | 1 + 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/core/src/main/scala/coulomb/deltaquantity.scala b/core/src/main/scala/coulomb/deltaquantity.scala index 344ab6b3e..9f915141a 100644 --- a/core/src/main/scala/coulomb/deltaquantity.scala +++ b/core/src/main/scala/coulomb/deltaquantity.scala @@ -83,7 +83,7 @@ object deltaquantity: sub.eval(ql, qr) transparent inline def +[VR, UR](qr: Quantity[VR, UR])(using add: DeltaAddQ[B, VL, UL, VR, UR]): DeltaQuantity[add.VO, add.UO, B] = - add(ql, qr) + add.eval(ql, qr) inline def ===[VR, UR](qr: DeltaQuantity[VR, UR, B])(using ord: DeltaOrd[B, VL, UL, VR, UR]): Boolean = ord(ql, qr) == 0 diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 0d220e545..338fd62d8 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -84,7 +84,7 @@ abstract class DeltaSubQ[B, VL, UL, VR, UR]: abstract class DeltaAddQ[B, VL, UL, VR, UR]: type VO type UO - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] + val eval: (DeltaQuantity[VL, UL, B], Quantity[VR, UR]) => DeltaQuantity[VO, UO, B] @implicitNotFound("Ordering not defined in scope for DeltaQuantity[${VL}, ${UL}] and DeltaQuantity[${VR}, ${UR}]") abstract class DeltaOrd[B, VL, UL, VR, UR]: diff --git a/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala b/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala index b3bc7b64f..a4676eca7 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltaaddq.scala @@ -30,7 +30,7 @@ object deltaaddq: equ: UR =:= UL, alg: AdditiveSemigroup[VL] ): DeltaAddQ[B, VL, UL, VR, UR] = - new infra.DeltaAddQ1V1U[B, VL, UL, VR, UR](alg, eqv) + new infra.DeltaAddQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.plus(ql.value, eqv(qr.value)).withDeltaUnit[UL, B]) transparent inline given ctx_deltaaddq_1V2U[B, VL, UL, VR, UR](using eqv: VR =:= VL, @@ -38,7 +38,7 @@ object deltaaddq: icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]], alg: AdditiveSemigroup[VL] ): DeltaAddQ[B, VL, UL, VR, UR] = - new infra.DeltaAddQ1V2U[B, VL, UL, VR, UR](alg, icr) + new infra.DeltaAddQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.plus(ql.value, icr(qr).value).withDeltaUnit[UL, B]) transparent inline given ctx_deltaaddq_2V1U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -48,7 +48,7 @@ object deltaaddq: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveSemigroup[vres.VO] ): DeltaAddQ[B, VL, UL, VR, UR] = - new infra.DeltaAddQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + new infra.DeltaAddQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withDeltaUnit[UL, B]) transparent inline given ctx_deltaaddq_2V2U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], @@ -58,30 +58,9 @@ object deltaaddq: icr: Conversion[Quantity[VR, UR], Quantity[vres.VO, UL]], alg: AdditiveSemigroup[vres.VO] ): DeltaAddQ[B, VL, UL, VR, UR] = - new infra.DeltaAddQ2V2U[B, VL, UL, VR, UR, vres.VO](alg, icl, icr) + new infra.DeltaAddQNC((ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]) => alg.plus(icl(ql).value, icr(qr).value).withDeltaUnit[UL, B]) object infra: - class DeltaAddQ1V1U[B, VL, UL, VR, UR]( - alg: AdditiveSemigroup[VL], - eqv: VR =:= VL) extends DeltaAddQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(ql.value, eqv(qr.value)).withDeltaUnit[UO, B] - - class DeltaAddQ1V2U[B, VL, UL, VR, UR]( - alg: AdditiveSemigroup[VL], - icr: Conversion[Quantity[VR, UR], Quantity[VL, UL]]) extends DeltaAddQ[B, VL, UL, VR, UR]: - type VO = VL - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(ql.value, icr(qr).value).withDeltaUnit[UO, B] - - class DeltaAddQ2V2U[B, VL, UL, VR, UR, VOp]( - alg: AdditiveSemigroup[VOp], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], - icr: Conversion[Quantity[VR, UR], Quantity[VOp, UL]]) extends DeltaAddQ[B, VL, UL, VR, UR]: + class DeltaAddQNC[B, VL, UL, VR, UR, VOp, UOp](val eval: (DeltaQuantity[VL, UL, B], Quantity[VR, UR]) => DeltaQuantity[VOp, UOp, B]) extends DeltaAddQ[B, VL, UL, VR, UR]: type VO = VOp - type UO = UL - def apply(ql: DeltaQuantity[VL, UL, B], qr: Quantity[VR, UR]): DeltaQuantity[VO, UO, B] = - alg.plus(icl(ql).value, icr(qr).value).withDeltaUnit[UO, B] + type UO = UOp diff --git a/core/src/main/scala/coulomb/ops/standard/named.scala b/core/src/main/scala/coulomb/ops/standard/named.scala index af29e9af8..60fde559b 100644 --- a/core/src/main/scala/coulomb/ops/standard/named.scala +++ b/core/src/main/scala/coulomb/ops/standard/named.scala @@ -26,4 +26,5 @@ object named: export tpow.infra.TPowNC export deltasub.infra.DeltaSubNC export deltasubq.infra.DeltaSubQNC + export deltaaddq.infra.DeltaAddQNC From 26ed1ee0e1d378807574bbc1f7740e6ebd456818 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 15:49:36 -0700 Subject: [PATCH 32/35] DeltaOrd with SAM/lambdas --- core/src/main/scala/coulomb/ops/ops.scala | 3 +- .../scala/coulomb/ops/standard/deltaord.scala | 37 ++++--------------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/ops.scala b/core/src/main/scala/coulomb/ops/ops.scala index 338fd62d8..2378044ca 100644 --- a/core/src/main/scala/coulomb/ops/ops.scala +++ b/core/src/main/scala/coulomb/ops/ops.scala @@ -87,8 +87,7 @@ abstract class DeltaAddQ[B, VL, UL, VR, UR]: val eval: (DeltaQuantity[VL, UL, B], Quantity[VR, UR]) => DeltaQuantity[VO, UO, B] @implicitNotFound("Ordering not defined in scope for DeltaQuantity[${VL}, ${UL}] and DeltaQuantity[${VR}, ${UR}]") -abstract class DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int +abstract class DeltaOrd[B, VL, UL, VR, UR] extends ((DeltaQuantity[VL, UL, B], DeltaQuantity[VR, UR, B]) => Int) /** Resolve the operator output type for left and right argument types */ @implicitNotFound("No output type resolution in scope for argument value types ${VL} and ${VR}") diff --git a/core/src/main/scala/coulomb/ops/standard/deltaord.scala b/core/src/main/scala/coulomb/ops/standard/deltaord.scala index 7a3f42b72..fc8729bee 100644 --- a/core/src/main/scala/coulomb/ops/standard/deltaord.scala +++ b/core/src/main/scala/coulomb/ops/standard/deltaord.scala @@ -25,22 +25,22 @@ object deltaord: import coulomb.* import coulomb.ops.{DeltaOrd, ValueResolution} - transparent inline given ctx_deltaord_1V1U[B, VL, UL, VR, UR](using + given ctx_deltaord_1V1U[B, VL, UL, VR, UR](using eqv: VR =:= VL, equ: UR =:= UL, ord: Order[VL] ): DeltaOrd[B, VL, UL, VR, UR] = - new infra.DeltaOrd1V1U[B, VL, UL, VR, UR](ord, eqv) + (ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => ord.compare(ql.value, eqv(qr.value)) - transparent inline given ctx_deltaord_1V2U[B, VL, UL, VR, UR](using + given ctx_deltaord_1V2U[B, VL, UL, VR, UR](using eqv: VR =:= VL, neu: NotGiven[UR =:= UL], icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]], ord: Order[VL] ): DeltaOrd[B, VL, UL, VR, UR] = - new infra.DeltaOrd1V2U[B, VL, UL, VR, UR](ord, icr) + (ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => ord.compare(ql.value, icr(qr).value) - transparent inline given ctx_deltaord_2V1U[B, VL, UL, VR, UR](using + given ctx_deltaord_2V1U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], equ: UR =:= UL, vres: ValueResolution[VL, VR], @@ -48,9 +48,9 @@ object deltaord: icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], ord: Order[vres.VO] ): DeltaOrd[B, VL, UL, VR, UR] = - new infra.DeltaOrd2V2U[B, VL, UL, VR, UR, vres.VO](ord, icl, icr) + (ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => ord.compare(icl(ql).value, icr(qr).value) - transparent inline given ctx_deltaord_2V2U[B, VL, UL, VR, UR](using + given ctx_deltaord_2V2U[B, VL, UL, VR, UR](using nev: NotGiven[VR =:= VL], neu: NotGiven[UR =:= UL], vres: ValueResolution[VL, VR], @@ -58,25 +58,4 @@ object deltaord: icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[vres.VO, UL, B]], ord: Order[vres.VO] ): DeltaOrd[B, VL, UL, VR, UR] = - new infra.DeltaOrd2V2U[B, VL, UL, VR, UR, vres.VO](ord, icl, icr) - - object infra: - class DeltaOrd1V1U[B, VL, UL, VR, UR]( - ord: Order[VL], - eqv: VR =:= VL) extends DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(ql.value, eqv(qr.value)) - - class DeltaOrd1V2U[B, VL, UL, VR, UR]( - ord: Order[VL], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VL, UL, B]]) extends DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(ql.value, icr(qr).value) - - class DeltaOrd2V2U[B, VL, UL, VR, UR, VOp]( - ord: Order[VOp], - icl: Conversion[DeltaQuantity[VL, UL, B], DeltaQuantity[VOp, UL, B]], - icr: Conversion[DeltaQuantity[VR, UR, B], DeltaQuantity[VOp, UL, B]]) extends DeltaOrd[B, VL, UL, VR, UR]: - def apply(ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]): Int = - ord.compare(icl(ql).value, icr(qr).value) - + (ql: DeltaQuantity[VL, UL, B], qr: DeltaQuantity[VR, UR, B]) => ord.compare(icl(ql).value, icr(qr).value) From e84558bc59bfb01ac23746c45a37bbc103a33652 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 16:40:30 -0700 Subject: [PATCH 33/35] VRNC --- .../coulomb/ops/resolution/standard.scala | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/core/src/main/scala/coulomb/ops/resolution/standard.scala b/core/src/main/scala/coulomb/ops/resolution/standard.scala index 2c80206b6..4feaf83c9 100644 --- a/core/src/main/scala/coulomb/ops/resolution/standard.scala +++ b/core/src/main/scala/coulomb/ops/resolution/standard.scala @@ -19,50 +19,54 @@ package coulomb.ops.resolution object standard: import coulomb.ops.ValueResolution - given ctx_VR_Double_Double: ValueResolution[Double, Double] with - type VO = Double + transparent inline given ctx_VR_Double_Double: ValueResolution[Double, Double] = + new infra.VRNC[Double, Double, Double] - given ctx_VR_Double_Float: ValueResolution[Double, Float] with - type VO = Double + transparent inline given ctx_VR_Double_Float: ValueResolution[Double, Float] = + new infra.VRNC[Double, Float, Double] - given ctx_VR_Double_Long: ValueResolution[Double, Long] with - type VO = Double + transparent inline given ctx_VR_Double_Long: ValueResolution[Double, Long] = + new infra.VRNC[Double, Long, Double] - given ctx_VR_Double_Int: ValueResolution[Double, Int] with - type VO = Double + transparent inline given ctx_VR_Double_Int: ValueResolution[Double, Int] = + new infra.VRNC[Double, Int, Double] - given ctx_VR_Float_Double: ValueResolution[Float, Double] with - type VO = Double + transparent inline given ctx_VR_Float_Double: ValueResolution[Float, Double] = + new infra.VRNC[Float, Double, Double] - given ctx_VR_Float_Float: ValueResolution[Float, Float] with - type VO = Float + transparent inline given ctx_VR_Float_Float: ValueResolution[Float, Float] = + new infra.VRNC[Float, Float, Float] - given ctx_VR_Float_Long: ValueResolution[Float, Long] with - type VO = Float + transparent inline given ctx_VR_Float_Long: ValueResolution[Float, Long] = + new infra.VRNC[Float, Long, Float] - given ctx_VR_Float_Int: ValueResolution[Float, Int] with - type VO = Float + transparent inline given ctx_VR_Float_Int: ValueResolution[Float, Int] = + new infra.VRNC[Float, Int, Float] - given ctx_VR_Long_Double: ValueResolution[Long, Double] with - type VO = Double + transparent inline given ctx_VR_Long_Double: ValueResolution[Long, Double] = + new infra.VRNC[Long, Double, Double] - given ctx_VR_Long_Float: ValueResolution[Long, Float] with - type VO = Float + transparent inline given ctx_VR_Long_Float: ValueResolution[Long, Float] = + new infra.VRNC[Long, Float, Float] - given ctx_VR_Long_Long: ValueResolution[Long, Long] with - type VO = Long + transparent inline given ctx_VR_Long_Long: ValueResolution[Long, Long] = + new infra.VRNC[Long, Long, Long] - given ctx_VR_Long_Int: ValueResolution[Long, Int] with - type VO = Long + transparent inline given ctx_VR_Long_Int: ValueResolution[Long, Int] = + new infra.VRNC[Long, Int, Long] - given ctx_VR_Int_Double: ValueResolution[Int, Double] with - type VO = Double + transparent inline given ctx_VR_Int_Double: ValueResolution[Int, Double] = + new infra.VRNC[Int, Double, Double] - given ctx_VR_Int_Float: ValueResolution[Int, Float] with - type VO = Float + transparent inline given ctx_VR_Int_Float: ValueResolution[Int, Float] = + new infra.VRNC[Int, Float, Float] - given ctx_VR_Int_Long: ValueResolution[Int, Long] with - type VO = Long + transparent inline given ctx_VR_Int_Long: ValueResolution[Int, Long] = + new infra.VRNC[Int, Long, Long] - given ctx_VR_Int_Int: ValueResolution[Int, Int] with - type VO = Int + transparent inline given ctx_VR_Int_Int: ValueResolution[Int, Int] = + new infra.VRNC[Int, Int, Int] + + object infra: + class VRNC[VL, VR, VOp] extends ValueResolution[VL, VR]: + type VO = VOp From b0872d86a3942b1af03b33219d7542b27b1dcc23 Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 17:51:12 -0700 Subject: [PATCH 34/35] policy cleanup --- .../coulomb/conversion/standard/all.scala | 22 ---- .../conversion/standard/explicit.scala | 21 ---- .../main/scala/coulomb/ops/standard/all.scala | 31 +++-- core/src/main/scala/coulomb/policy.scala | 20 ++-- .../test/scala/coulomb/deltaquantity.scala | 44 ++----- core/src/test/scala/coulomb/quantity.scala | 111 ++++++------------ units/src/test/scala/coulomb/si.scala | 3 +- .../src/test/scala/coulomb/temperature.scala | 22 ++-- units/src/test/scala/coulomb/time.scala | 46 ++------ 9 files changed, 93 insertions(+), 227 deletions(-) delete mode 100644 core/src/main/scala/coulomb/conversion/standard/all.scala delete mode 100644 core/src/main/scala/coulomb/conversion/standard/explicit.scala diff --git a/core/src/main/scala/coulomb/conversion/standard/all.scala b/core/src/main/scala/coulomb/conversion/standard/all.scala deleted file mode 100644 index 5423033ff..000000000 --- a/core/src/main/scala/coulomb/conversion/standard/all.scala +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2022 Erik Erlandson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package coulomb.conversion.standard - -object all: - export coulomb.conversion.standard.value.given - export coulomb.conversion.standard.unit.given - export coulomb.conversion.standard.scala.given diff --git a/core/src/main/scala/coulomb/conversion/standard/explicit.scala b/core/src/main/scala/coulomb/conversion/standard/explicit.scala deleted file mode 100644 index f10c0d55e..000000000 --- a/core/src/main/scala/coulomb/conversion/standard/explicit.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2022 Erik Erlandson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package coulomb.conversion.standard - -object explicit: - export coulomb.conversion.standard.value.given - export coulomb.conversion.standard.unit.given diff --git a/core/src/main/scala/coulomb/ops/standard/all.scala b/core/src/main/scala/coulomb/ops/standard/all.scala index e9d54d8f2..76cd84f4a 100644 --- a/core/src/main/scala/coulomb/ops/standard/all.scala +++ b/core/src/main/scala/coulomb/ops/standard/all.scala @@ -16,20 +16,17 @@ package coulomb.ops.standard -// eventually these go in `object all` -export neg.given -export add.given -export sub.given -export mul.given -export div.given -export tquot.given -export pow.given -export tpow.given -export ord.given -export deltasub.given -export deltasubq.given -export deltaaddq.given -export deltaord.given - -// will be exported via policies -export coulomb.ops.simplification.standard.given +object all: + export neg.given + export add.given + export sub.given + export mul.given + export div.given + export tquot.given + export pow.given + export tpow.given + export ord.given + export deltasub.given + export deltasubq.given + export deltaaddq.given + export deltaord.given diff --git a/core/src/main/scala/coulomb/policy.scala b/core/src/main/scala/coulomb/policy.scala index 4877f78f8..24a407af9 100644 --- a/core/src/main/scala/coulomb/policy.scala +++ b/core/src/main/scala/coulomb/policy.scala @@ -18,22 +18,24 @@ package coulomb object policy: /** - * A "standard" policy that supports all operations, including those involving + * A policy that supports all standard operation definitions, including those involving * implicit conversions of units or value types. * * {{{ * import coulomb.* * import coulomb.policy.standard.given + * + * import algebra.instances.all.given + * import coulomb.ops.algebra.all.given * }}} */ object standard: - // export algebra.instances.all.given - // export coulomb.ops.standard.given - export coulomb.ops.algebra.all.given + export coulomb.ops.standard.all.given + export coulomb.ops.simplification.standard.given + export coulomb.ops.resolution.standard.given export coulomb.conversion.standard.value.given export coulomb.conversion.standard.unit.given export coulomb.conversion.standard.scala.given - export coulomb.ops.standard.optimizations.all.given /** * A policy that supports all standard operations, but does not support operations that @@ -46,12 +48,14 @@ object policy: * {{{ * import coulomb.* * import coulomb.policy.strict.given + * + * import algebra.instances.all.given + * import coulomb.ops.algebra.all.given * }}} */ object strict: - // export algebra.instances.all.given - // export coulomb.ops.standard.given - export coulomb.ops.algebra.all.given + export coulomb.ops.standard.all.given + export coulomb.ops.simplification.standard.given export coulomb.conversion.standard.value.given export coulomb.conversion.standard.unit.given diff --git a/core/src/test/scala/coulomb/deltaquantity.scala b/core/src/test/scala/coulomb/deltaquantity.scala index 7555eef4e..303e3bea2 100644 --- a/core/src/test/scala/coulomb/deltaquantity.scala +++ b/core/src/test/scala/coulomb/deltaquantity.scala @@ -54,8 +54,9 @@ class DeltaQuantitySuite extends CoulombSuite: assertEquals(1.withDeltaUnit[Second, Second].showFull, "1 second") } - test("toValue standard") { - import coulomb.conversion.standard.value.given + test("toValue") { + import coulomb.policy.strict.given + 100.withDeltaUnit[Celsius, Kelvin].toValue[Int].assertDQ[Int, Celsius](100) 100.withDeltaUnit[Celsius, Kelvin].toValue[Long].assertDQ[Long, Celsius](100) 100.withDeltaUnit[Celsius, Kelvin].toValue[Float].assertDQ[Float, Celsius](100) @@ -75,10 +76,7 @@ class DeltaQuantitySuite extends CoulombSuite: assertCE("100d.withDeltaUnit[Celsius, Kelvin].toValue[Long]") 100d.withDeltaUnit[Celsius, Kelvin].toValue[Float].assertDQ[Float, Celsius](100) 100d.withDeltaUnit[Celsius, Kelvin].toValue[Double].assertDQ[Double, Celsius](100) - } - test("toValue standard truncating") { - import coulomb.conversion.standard.value.given 1.999f.withDeltaUnit[Minute, Second].tToValue[Int].assertDQ[Int, Minute](1) 0.999f.withDeltaUnit[Minute, Second].tToValue[Long].assertDQ[Long, Minute](0) @@ -86,26 +84,21 @@ class DeltaQuantitySuite extends CoulombSuite: 0.999d.withDeltaUnit[Minute, Second].tToValue[Long].assertDQ[Long, Minute](0) } - test("toUnit standard") { - import coulomb.conversion.standard.explicit.given + test("toUnit") { + import coulomb.policy.strict.given 37d.withDeltaUnit[Celsius, Kelvin].toUnit[Fahrenheit].assertDQD[Double, Fahrenheit](98.6) 37f.withDeltaUnit[Celsius, Kelvin].toUnit[Fahrenheit].assertDQD[Float, Fahrenheit](98.6) assertCE("37L.withDeltaUnit[Celsius, Kelvin].toUnit[Fahrenheit]") assertCE("37.withDeltaUnit[Celsius, Kelvin].toUnit[Fahrenheit]") - } - - test("toUnit standard truncating") { - import coulomb.conversion.standard.explicit.given 37L.withDeltaUnit[Celsius, Kelvin].tToUnit[Fahrenheit].assertDQ[Long, Fahrenheit](98) 37.withDeltaUnit[Celsius, Kelvin].tToUnit[Fahrenheit].assertDQ[Int, Fahrenheit](98) } test("subtraction strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given // 1V1U (100d.withDeltaUnit[Celsius, Kelvin] - 50d.withDeltaUnit[Celsius, Kelvin]).assertQ[Double, Celsius](50) @@ -115,9 +108,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // 2V1U (100d.withDeltaUnit[Celsius, Kelvin] - 50f.withDeltaUnit[Celsius, Kelvin]).assertQ[Double, Celsius](50) @@ -128,8 +119,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("quantity subtraction strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given // 1V1U (100d.withDeltaUnit[Celsius, Kelvin] - 50d.withUnit[Celsius]).assertDQ[Double, Celsius](50) @@ -139,9 +129,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("quantity subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // 2V1U (100d.withDeltaUnit[Celsius, Kelvin] - 50f.withUnit[Celsius]).assertDQ[Double, Celsius](50) @@ -152,8 +140,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("quantity addition strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given // 1V1U (100d.withDeltaUnit[Celsius, Kelvin] + 50d.withUnit[Celsius]).assertDQ[Double, Celsius](150) @@ -163,9 +150,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("quantity addition standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // 2V1U (100d.withDeltaUnit[Celsius, Kelvin] + 50f.withUnit[Celsius]).assertDQ[Double, Celsius](150) @@ -176,8 +161,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("less-than strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given assertEquals(7d.withDeltaUnit[Minute, Second] < 8d.withDeltaUnit[Minute, Second], true) assertEquals(7f.withDeltaUnit[Minute, Second] < 7f.withDeltaUnit[Minute, Second], false) @@ -186,9 +170,7 @@ class DeltaQuantitySuite extends CoulombSuite: } test("less-than standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // 1V2U assertEquals(36d.withDeltaUnit[Celsius, Kelvin] < 98.6d.withDeltaUnit[Fahrenheit, Kelvin], true) diff --git a/core/src/test/scala/coulomb/quantity.scala b/core/src/test/scala/coulomb/quantity.scala index 1902cfbc9..3969ff91f 100644 --- a/core/src/test/scala/coulomb/quantity.scala +++ b/core/src/test/scala/coulomb/quantity.scala @@ -54,8 +54,8 @@ class QuantitySuite extends CoulombSuite: assertEquals(1.withUnit[Second].showFull, "1 second") } - test("toValue standard") { - import coulomb.conversion.standard.value.given + test("toValue") { + import coulomb.policy.strict.given 1.withUnit[Meter].toValue[Int].assertQ[Int, Meter](1) 1.withUnit[Meter].toValue[Long].assertQ[Long, Meter](1) @@ -76,10 +76,6 @@ class QuantitySuite extends CoulombSuite: assertCE("1d.withUnit[Meter].toValue[Long]") 1d.withUnit[Meter].toValue[Float].assertQ[Float, Meter](1) 1d.withUnit[Meter].toValue[Double].assertQ[Double, Meter](1) - } - - test("toValue standard truncating") { - import coulomb.conversion.standard.value.given 1.5f.withUnit[Meter].tToValue[Int].assertQ[Int, Meter](1) 0.999f.withUnit[Meter].tToValue[Long].assertQ[Long, Meter](0) @@ -88,28 +84,24 @@ class QuantitySuite extends CoulombSuite: 0.999d.withUnit[Meter].tToValue[Long].assertQ[Long, Meter](0) } - test("toUnit standard") { - import coulomb.conversion.standard.explicit.given + test("toUnit") { + import coulomb.policy.strict.given 1.5f.withUnit[Minute].toUnit[Second].assertQ[Float, Second](90) 1d.withUnit[Meter].toUnit[Yard].assertQD[Double, Yard](1.0936132983377078) assertCE("1.withUnit[Minute].toUnit[Second]") assertCE("1L.withUnit[Yard].toUnit[Meter]") - } - - test("toUnit standard truncating") { - import coulomb.conversion.standard.unit.given 1.withUnit[Minute].tToUnit[Second].assertQ[Int, Second](60) 1L.withUnit[Yard].tToUnit[Meter].assertQ[Long, Meter](0) } test("implicit conversions") { - import coulomb.conversion.standard.explicit.given + // strict policy does not include implicit conversions + import coulomb.policy.strict.given - // implicit conversions only happen if you import them, - // and set coulomb policy to allow them + // implicit conversions only happen if you import them into scope // https://docs.scala-lang.org/scala3/reference/contextual/conversions.html def f(q: Quantity[Double, Meter]): Double = q.value assertCE("f(1d.withUnit[Yard])") @@ -119,16 +111,15 @@ class QuantitySuite extends CoulombSuite: f(1.withUnit[Meter].toValue[Double]).assertVTD[Double](1.0) object t { - // enabling implicit conversions should allow them + // standard policy puts implicit conversions in scope + import coulomb.policy.standard.given import scala.language.implicitConversions - import coulomb.conversion.standard.scala.given f(1d.withUnit[Yard]).assertVTD[Double](0.9144) } } - test("addition standard strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + test("addition strict") { + import coulomb.policy.strict.given // adding w/ same value and unit requires no implicit conversion (1d.withUnit[Second] + 1d.withUnit[Second]).assertQ[Double, Second](2) @@ -146,9 +137,7 @@ class QuantitySuite extends CoulombSuite: } test("addition standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // same value type, different units (1d.withUnit[Kilo * Second] + 1d.withUnit[Second]).assertQD[Double, Kilo * Second](1.001) @@ -194,13 +183,8 @@ class QuantitySuite extends CoulombSuite: // unsafe truncating conversions should fail assertCE("1.withUnit[Meter] + 1.withUnit[Yard]") assertCE("1L.withUnit[Meter] + 1L.withUnit[Yard]") - } - - test("addition standard truncating") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + // truncating (1L.withUnit[Second] + 1L.withUnit[Minute].tToUnit[Second]).assertQ[Long, Second](61) (1L.withUnit[Second] + 1.withUnit[Minute].tToUnit[Second]).assertQ[Long, Second](61) (1.withUnit[Second] + 1L.withUnit[Minute].tToUnit[Second]).assertQ[Long, Second](61) @@ -217,9 +201,8 @@ class QuantitySuite extends CoulombSuite: (1L.withUnit[Yard] + 3L.withUnit[Foot].tToUnit[Yard]).assertQ[Long, Yard](2) } - test("subtraction standard strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + test("subtraction strict") { + import coulomb.policy.strict.given // same value and unit requires no implicit conversion (3d.withUnit[Second] - 1d.withUnit[Second]).assertQ[Double, Second](2) @@ -237,9 +220,7 @@ class QuantitySuite extends CoulombSuite: } test("subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // same value type, different units (1d.withUnit[Kilo * Second] - 1d.withUnit[Second]).assertQD[Double, Kilo * Second](0.999) @@ -285,13 +266,8 @@ class QuantitySuite extends CoulombSuite: // unsafe truncating conversions should fail assertCE("1.withUnit[Meter] - 1.withUnit[Yard]") assertCE("1L.withUnit[Meter] - 1L.withUnit[Yard]") - } - - test("subtraction standard truncating") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + // truncating (61L.withUnit[Second] - 1L.withUnit[Minute].tToUnit[Second]).assertQ[Long, Second](1) (61L.withUnit[Second] - 1.withUnit[Minute].tToUnit[Second]).assertQ[Long, Second](1) (61.withUnit[Second] - 1L.withUnit[Minute].tToUnit[Second]).assertQ[Long, Second](1) @@ -308,9 +284,8 @@ class QuantitySuite extends CoulombSuite: (2L.withUnit[Yard] - 3L.withUnit[Foot].tToUnit[Yard]).assertQ[Long, Yard](1) } - test("multiplication standard strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + test("multiplication strict") { + import coulomb.policy.strict.given // same value types require no implicit conversion (2d.withUnit[Meter] * 3d.withUnit[Meter]).assertQ[Double, Meter ^ 2](6) @@ -327,9 +302,7 @@ class QuantitySuite extends CoulombSuite: } test("multiplication standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // differing value types (3d.withUnit[Meter] * 5d.withUnit[Meter]).assertQ[Double, Meter ^ 2](15) @@ -353,9 +326,8 @@ class QuantitySuite extends CoulombSuite: (3.withUnit[Second] * 5.withUnit[Kilogram]).assertQ[Int, Second * Kilogram](15) } - test("division standard strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + test("division strict") { + import coulomb.policy.strict.given // same value types require no implicit conversion (12d.withUnit[Meter] / 3d.withUnit[Second]).assertQ[Double, Meter / Second](4) @@ -373,9 +345,7 @@ class QuantitySuite extends CoulombSuite: } test("division standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given (5d.withUnit[Meter] / 2d.withUnit[Second]).assertQ[Double, Meter / Second](2.5) (5d.withUnit[Meter] / 2f.withUnit[Second]).assertQ[Double, Meter / Second](2.5) @@ -399,9 +369,7 @@ class QuantitySuite extends CoulombSuite: } test("truncating division standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given (5d.withUnit[Meter] `tquot` 2d.withUnit[Second]).assertQ[Double, Meter / Second](2) (5f.withUnit[Meter] `tquot` 2f.withUnit[Second]).assertQ[Float, Meter / Second](2) @@ -414,8 +382,7 @@ class QuantitySuite extends CoulombSuite: } test("power standard") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given 2d.withUnit[Meter].pow[0].assertQ[Double, 1](1) 2d.withUnit[Meter].pow[2].assertQ[Double, Meter ^ 2](4) @@ -444,8 +411,7 @@ class QuantitySuite extends CoulombSuite: } test("truncating power standard") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given 10d.withUnit[Meter].tpow[0].assertQ[Double, 1](1) 10d.withUnit[Meter].tpow[2].assertQ[Double, Meter ^ 2](100) @@ -473,9 +439,7 @@ class QuantitySuite extends CoulombSuite: } test("constants in simplified unit types") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // changes/improvements to simplification algorithm may change these - // it is more important that they be correct than have some particular form, but @@ -489,7 +453,7 @@ class QuantitySuite extends CoulombSuite: } test("negation standard") { - import coulomb.ops.standard.given + import coulomb.policy.standard.given (-(7d.withUnit[Liter])).assertQ[Double, Liter](-7) (-(7f.withUnit[Liter])).assertQ[Float, Liter](-7) @@ -497,9 +461,8 @@ class QuantitySuite extends CoulombSuite: (-(7.withUnit[Liter])).assertQ[Int, Liter](-7) } - test("equality standard strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + test("equality strict") { + import coulomb.policy.strict.given assertEquals(1d.withUnit[Meter] === 1d.withUnit[Meter], true) assertEquals(1f.withUnit[Meter] === 1f.withUnit[Meter], true) @@ -516,9 +479,7 @@ class QuantitySuite extends CoulombSuite: } test("equality standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given assertEquals(2d.withUnit[(1 / 2) * Meter] === 1d.withUnit[Meter], true) assertEquals(2d.withUnit[(1 / 2) * Meter] === 2f.withUnit[Meter], false) @@ -539,13 +500,8 @@ class QuantitySuite extends CoulombSuite: assertEquals(2.withUnit[(1 / 2) * Meter] === 1f.withUnit[Meter], true) assertCE("2.withUnit[(1 / 2) * Meter] === 1L.withUnit[Meter]") assertCE("2.withUnit[(1 / 2) * Meter] === 1.withUnit[Meter]") - } - - test("equality standard truncating") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + // truncating assertEquals(2L.withUnit[(1 / 2) * Meter] === 1d.withUnit[Meter], true) assertEquals(2L.withUnit[(1 / 2) * Meter] === 2f.withUnit[Meter], false) assertEquals(2L.withUnit[(1 / 2) * Meter].tToUnit[Meter] === 1L.withUnit[Meter], true) @@ -563,13 +519,12 @@ class OptimizedQuantitySuite extends CoulombSuite: import algebra.instances.all.given import coulomb.ops.algebra.all.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // I need to test with optimizations in scope // it would be ideal to somehow compile the main QuantitySuite with // and without these optimizations import coulomb.ops.standard.optimizations.all.given - import coulomb.ops.standard.given // it is important that non-optimized be imported at the same scope level (or higher) // otherwise it will override the optimizations if it is at narrower scope diff --git a/units/src/test/scala/coulomb/si.scala b/units/src/test/scala/coulomb/si.scala index 51f1164be..4478422af 100644 --- a/units/src/test/scala/coulomb/si.scala +++ b/units/src/test/scala/coulomb/si.scala @@ -20,7 +20,8 @@ class SIUnitsSuite extends CoulombSuite: import coulomb.* import coulomb.units.si.{*, given} import coulomb.units.si.prefixes.{*, given} - import coulomb.conversion.standard.all.given + + import coulomb.policy.standard.given test("defines si units") { 1.withUnit[Meter].assertQ[Int, Meter](1) diff --git a/units/src/test/scala/coulomb/temperature.scala b/units/src/test/scala/coulomb/temperature.scala index bc3c4d555..0ec008def 100644 --- a/units/src/test/scala/coulomb/temperature.scala +++ b/units/src/test/scala/coulomb/temperature.scala @@ -52,45 +52,39 @@ class TemperatureUnitsSuite extends CoulombSuite: } test("toValue") { - import coulomb.conversion.standard.value.given + import coulomb.policy.strict.given + 1.withTemperature[Celsius].toValue[Float].assertDQ[Float, Celsius](1) 1d.withTemperature[Celsius].tToValue[Int].assertDQ[Int, Celsius](1) } test("toUnit") { - import coulomb.conversion.standard.all.given + import coulomb.policy.strict.given + 37d.withTemperature[Celsius].toUnit[Fahrenheit].assertDQD[Double, Fahrenheit](98.6) 37.withTemperature[Celsius].tToUnit[Fahrenheit].assertDQD[Int, Fahrenheit](98) } test("subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given (100.withTemperature[Celsius] - 122d.withTemperature[Fahrenheit]).assertQD[Double, Celsius](50) } test("quantity subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given (100.withTemperature[Celsius] - 90d.withUnit[Fahrenheit]).assertDQD[Double, Celsius](50) } test("quantity addition standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given (100.withTemperature[Celsius] + 90d.withUnit[Fahrenheit]).assertDQD[Double, Celsius](150) } test("less-than standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given assertEquals(100d.withTemperature[Celsius] < 100f.withTemperature[Fahrenheit], false) assertEquals(0f.withTemperature[Fahrenheit] < 0L.withTemperature[Celsius], true) diff --git a/units/src/test/scala/coulomb/time.scala b/units/src/test/scala/coulomb/time.scala index 50a62b6ac..e1319c568 100644 --- a/units/src/test/scala/coulomb/time.scala +++ b/units/src/test/scala/coulomb/time.scala @@ -57,7 +57,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("toValue") { - import coulomb.conversion.standard.value.given + import coulomb.policy.standard.given 1d.withEpochTime[Second].toValue[Float].assertDQ[Float, Second](1) 1L.withEpochTime[Second].toValue[Int].assertDQ[Int, Second](1) @@ -67,7 +67,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("toUnit") { - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given 36d.withEpochTime[Hour].toUnit[Day].assertDQD[Double, Day](1.5) @@ -77,8 +77,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("subtraction strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given (10d.withEpochTime[Second] - 1d.withEpochTime[Second]).assertQ[Double, Second](9) (10f.withEpochTime[Second] - 1f.withEpochTime[Second]).assertQ[Float, Second](9) @@ -91,9 +90,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // different value type, same unit type (61d.withEpochTime[Second] - 1f.withEpochTime[Second]).assertQ[Double, Second](60) @@ -108,8 +105,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("quantity subtraction strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given (10d.withEpochTime[Second] - 1d.withUnit[Second]).assertDQ[Double, Second](9) (10f.withEpochTime[Second] - 1f.withUnit[Second]).assertDQ[Float, Second](9) @@ -122,9 +118,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("quantity subtraction standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // different value type, same unit type (61d.withEpochTime[Second] - 1f.withUnit[Second]).assertDQ[Double, Second](60) @@ -139,8 +133,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("quantity addition strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given (10d.withEpochTime[Second] + 1d.withUnit[Second]).assertDQ[Double, Second](11) (10f.withEpochTime[Second] + 1f.withUnit[Second]).assertDQ[Float, Second](11) @@ -153,9 +146,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("quantity addition standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given // different value type, same unit type (61d.withEpochTime[Second] + 1f.withUnit[Second]).assertDQ[Double, Second](62) @@ -170,8 +161,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("less-than strict") { - import coulomb.ops.standard.given - import coulomb.conversion.standard.explicit.given + import coulomb.policy.strict.given assertEquals(3f.withEpochTime[Week] < 4f.withEpochTime[Week], true) assertEquals(4.withEpochTime[Week] < 4.withEpochTime[Week], false) @@ -184,9 +174,7 @@ class TimeUnitsSuite extends CoulombSuite: } test("less-than standard") { - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + import coulomb.policy.standard.given assertEquals(4f.withEpochTime[Week] < 4d.withEpochTime[Week], false) assertEquals(3f.withEpochTime[Day] < 3f.withEpochTime[Week], true) @@ -202,9 +190,9 @@ class JavaTimeSuite extends CoulombSuite: import coulomb.units.si.prefixes.{*, given} import coulomb.units.javatime.* import algebra.instances.all.given + import coulomb.policy.standard.given test("toQuantity") { - import coulomb.conversion.standard.all.given import coulomb.units.javatime.conversions.explicit.given val dur = Duration.ofSeconds(70, 400000000) @@ -216,8 +204,6 @@ class JavaTimeSuite extends CoulombSuite: } test("toDuration") { - import coulomb.conversion.standard.all.given - import coulomb.ops.standard.given import coulomb.units.javatime.conversions.explicit.given val q = 1d.withUnit[Hour] + 777.1d.withUnit[Nano * Second] @@ -227,7 +213,6 @@ class JavaTimeSuite extends CoulombSuite: } test("toEpochTime") { - import coulomb.conversion.standard.all.given import coulomb.units.javatime.conversions.explicit.given val ins = Instant.parse("1969-07-20T00:00:00Z") @@ -239,7 +224,6 @@ class JavaTimeSuite extends CoulombSuite: } test("toInstant") { - import coulomb.conversion.standard.all.given import coulomb.units.javatime.conversions.explicit.given val et = (-165L).withEpochTime[Day] @@ -248,8 +232,6 @@ class JavaTimeSuite extends CoulombSuite: test("implicit Q -> D") { import scala.language.implicitConversions - import coulomb.conversion.standard.all.given - import coulomb.ops.standard.given import coulomb.units.javatime.conversions.all.given def f(d: Duration): (Long, Int) = (d.getSeconds(), d.getNano()) @@ -259,8 +241,6 @@ class JavaTimeSuite extends CoulombSuite: test("implicit D -> Q") { import scala.language.implicitConversions - import coulomb.conversion.standard.all.given - import coulomb.ops.standard.given import coulomb.units.javatime.conversions.all.given def f(q: Quantity[Float, Minute]): Float = q.value @@ -270,8 +250,6 @@ class JavaTimeSuite extends CoulombSuite: test("implicit ET -> I") { import scala.language.implicitConversions - import coulomb.conversion.standard.all.given - import coulomb.ops.standard.given import coulomb.units.javatime.conversions.all.given def f(i: Instant): String = i.toString() @@ -281,8 +259,6 @@ class JavaTimeSuite extends CoulombSuite: test("implicit I -> ET") { import scala.language.implicitConversions - import coulomb.conversion.standard.all.given - import coulomb.ops.standard.given import coulomb.units.javatime.conversions.all.given def f(et: EpochTime[Double, Day]): Double = et.value From 658f02ae3c2135d5e5f623b84cf7ba694e832e9b Mon Sep 17 00:00:00 2001 From: Erik Erlandson Date: Tue, 5 Apr 2022 17:59:08 -0700 Subject: [PATCH 35/35] fix benchmark imports --- benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala b/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala index 5b1909811..fbfe8df2a 100644 --- a/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala +++ b/benchmarks/src/main/scala/coulomb/benchmarks/quantity.scala @@ -32,9 +32,8 @@ class QuantityBenchmark: import coulomb.testing.units.{*, given} import algebra.instances.all.given import coulomb.ops.algebra.all.given - import coulomb.ops.standard.given - import coulomb.ops.resolution.standard.given - import coulomb.conversion.standard.all.given + + import coulomb.policy.standard.given var data: Vector[Quantity[Double, Meter]] = Vector.empty[Quantity[Double, Meter]]