Giter Club home page Giter Club logo

Comments (5)

erikerlandson avatar erikerlandson commented on May 27, 2024

There are two basic approaches here, which could be described as:

  1. Refined is inside Quantity
  2. Refined is outside Quantity

I'm coming to the conclusion that the first is the more useful. However, the current Quantity design has baked in an implicit of Numeric[N] for a lot of operations, which works against putting Refined inside as-is.

If I factor out operations into an implicit class, I believe it will pave the way for supporting Quantity[Refined[N, P], U] in a more extensible way.

Such a refactorization is likely to represent a 0.5.x release series

from coulomb.

erikerlandson avatar erikerlandson commented on May 27, 2024

Closure. Refined values do not appear to be closed under arithmetic operations, which is sensible since in general doing operations on a value isn't guaranteed to preserve whatever refined predicates are in effect.

scala> val xx: Int Refined NonNegative = 2
xx: eu.timepit.refined.api.Refined[Int,eu.timepit.refined.numeric.NonNegative] = 2

scala> xx + 1
res23: Int = 3

Probably the same should be true for quantities of the form Quantity[Refined[N, P], U] - if some operation is applied then the result has type Quantity[N, U]

@fthomas I'm curious if you have any insights or opinions.

from coulomb.

fthomas avatar fthomas commented on May 27, 2024

You're correct about operations on refined types in general. Applying operations on refined values might make them invalid according to the predicate. But for some numeric refined types additive Semigroup / Monoid instances are provided which overflow according to their predicate:

scala> PosInt.MaxValue |+| PosInt(1)
res5: eu.timepit.refined.types.numeric.PosInt = 1

scala> NonNegInt.MaxValue |+| NonNegInt(1)
res6: eu.timepit.refined.types.numeric.NonNegInt = 0

Regarding if Refined should be inside Quantity or the other way round, I just want to note that most libraries that provide integration with refined are providing instances of their type classes for refined types so in these case Refined is always inside their type classes. But I don't have enough experience with coulomb to have an informed opinion on this matter. I guess you could argue for both depending on your predicate if it is refining the quantity/unit or just the value of the quantity.

from coulomb.

erikerlandson avatar erikerlandson commented on May 27, 2024

I have a solution for addressing closure. For Postive and NonNegative there are proper closed algebras for additive and multiplicative Semigroups/Monoids. These can be supported in a type-sound manner by default: if type checking compiles, there should be no runtime failures(*)

I will also support un-sound operations, on an opt-in basis. These are also properly validated for refined predicates, but at run-time, not compile time.

(*) there will actually be a couple edge cases here: division by zero in the case of NonNegative, and for Positive it will be possible for some unit conversions to round-down to zero, particularly when working with integer types.

from coulomb.

erikerlandson avatar erikerlandson commented on May 27, 2024

Implemented on release 0.4.5 (#73)

from coulomb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.