coulomb-refined
The coulomb-refined
package defines algebra typeclasses for integrating the
refined
typelevel libraries with coulomb
.
Quick Start
documentation
You can browse the coulomb-refined
api definitions
here.
packages
Include coulomb-refined
with your Scala project:
libraryDependencies += "com.manyangled" %% "coulomb-core" % "0.9.1"
libraryDependencies += "com.manyangled" %% "coulomb-refined" % "0.9.1"
import
// fundamental coulomb types and methods
import coulomb.*
import coulomb.syntax.*
// common refined definitions
import eu.timepit.refined.*
import eu.timepit.refined.api.*
import eu.timepit.refined.numeric.*
// algebraic definitions
import algebra.instances.all.given
// algebra typeclasses for refined integrations
import coulomb.integrations.refined.all.given
// coulomb syntax for refined integrations
import coulomb.integrations.refined.syntax.*
examples
Examples in this section will use the following workaround as a replacement for refineMV until it is ported forward to Scala 3.
// a workaround for refineMV not being available in scala3
// https://github.com/fthomas/refined/issues/932
object workaround:
extension [V](v: V)
def withRP[P](using Validate[V, P]): Refined[V, P] =
refineV[P].unsafeFrom(v)
import workaround.*
The coulomb-refined
package supports refined
predicates that are algebraically well-behaved for applicable operations.
Primarily this means the predicates
Positive
and
NonNegative.
For example, the positive doubles are an additive semigroup and multiplicative group,
as the following code demonstrates.
The
table
below summarizes the full list of supported refined
predicates and associated algebras.
import coulomb.units.si.{*, given}
import coulomb.units.us.{*, given}
val pos1 = 1d.withRP[Positive].withUnit[Meter]
// pos1: Quantity[(Double Refined Positive), Meter] = 1.0
val pos2 = 2d.withRP[Positive].withUnit[Meter]
// pos2: Quantity[(Double Refined Positive), Meter] = 2.0
val pos3 = 3d.withRP[Positive].withUnit[Second]
// pos3: Quantity[(Double Refined Positive), Second] = 3.0
// positive doubles are an additive semigroup
pos1 + pos2
// res0: Quantity[(Double Refined Positive), Meter] = 3.0
// also a multiplicative semigroup
pos1 * pos2
// res1: Quantity[(Double Refined Positive), ^[Meter, 2]] = 2.0
pos2.pow[2]
// res2: Quantity[(Double Refined Positive), ^[Meter, 2]] = 4.0
// also a multiplicative group
pos2 / pos3
// res3: Quantity[(Double Refined Positive), /[Meter, Second]] = 0.6666666666666666
pos2.pow[0]
// res4: Quantity[(Double Refined Positive), 1] = 1.0
The standard refined
function for refining values with run-time checking is
refineV,
which returns an
Either.
The coulomb-refined
package supplies a similar variation refinedVU
.
These objects are also supported by algebras.
// This refinement succeeds, and returns a Right value
val pe1 = refineVU[Positive, Meter](1)
// pe1: Quantity[Either[String, (Int Refined Positive)], Meter] = Right(
// value = 1
// )
// This refinement fails, and returns a Left value
val pe2 = refineVU[Positive, Meter](0)
// pe2: Quantity[Either[String, (Int Refined Positive)], Meter] = Left(
// value = "Predicate failed: (0 > 0)."
// )
// positives are an additive semigroup
pe1 + pe1
// res5: Quantity[Either[String, (Int Refined Positive)], Meter] = Right(
// value = 2
// )
// algebras operating on Left values result in a Left
pe1 + pe2
// res6: Quantity[Either[String, (Int Refined Positive)], Meter] = Left(
// value = "Predicate failed: (0 > 0)."
// )
algebra support table
The following table summarizes the algebras and operations supported by this package.
Examples of Fractional value types include Double
, Float
,
BigDecimal,
spire Rational, etc.
Integral value types include Int
, Long
, BigInt, etc.
Value Type | Predicate | Add Alg | Mult Alg | + |
* |
/ |
pow (exponent) |
---|---|---|---|---|---|---|---|
Fractional | Positive | semigroup | group | Y | Y | Y | Y (rational) |
Fractional | NonNegative | semigroup | semigroup | Y | Y | N | Y (pos int) |
Integral | Positive | semigroup | semigroup | Y | Y | N | Y (pos int) |
Integral | NonNegative | semigroup | semigroup | Y | Y | N | Y (pos int) |
The table above also applies to Either
objects returned by refineVU
as discussed
in the examples section above.