erikerlandson / coulomb

coulomb: unit analysis for Scala
https://erikerlandson.github.io/coulomb/
Apache License 2.0
142 stars 9 forks source link

scala3 questions #291

Open cquiroz opened 2 years ago

cquiroz commented 2 years ago

I did a first attempt trying to use coulomb in scala 3. I got quite a bit of progress on a relatively simple library that uses coulomb but I have some errors I can't solve, having tried several imports.

How could I get this work?

[error] -- Error: /Users/carlos.quiroz/code/noirlab/lucuma-itc/modules/itc/src/main/scala/lucuma/itc/ItcImpl.scala:150:40 
[error] 150 |                  ((expTime - oldExpTime) > 1.withUnit[Second] || (oldExpTime - expTime) > 1
[error]     |                                        ^
[error]     |Subtraction not defined in scope for Quantity[BigDecimal, coulomb.units.si.Second] and Quantity[BigDecimal, coulomb.units.si.Second]
[error]     |
[error]     |One of the following imports might make progress towards fixing the problem:
[error]     |
[error]     |  import coulomb.policy.spire.standard.ctx_sub_1V1U
[error]     |  import coulomb.policy.spire.standard.ctx_sub_1V2U
[error]     |  import coulomb.policy.spire.standard.ctx_sub_2V1U
[error]     |  import coulomb.policy.spire.standard.ctx_sub_2V2U
[error]     |  import coulomb.policy.spire.strict.ctx_sub_1V1U
[error]     |  import coulomb.policy.spire.strict.ctx_sub_1V2U
[error]     |  import coulomb.policy.spire.strict.ctx_sub_2V1U
[error]     |  import coulomb.policy.spire.strict.ctx_sub_2V2U
[error]     |  import coulomb.policy.standard.ctx_sub_1V1U
[error]     |  import coulomb.policy.standard.ctx_sub_1V2U

I'm importing

import coulomb.policy.spire.standard.`given`
import coulomb.ops.algebra.spire.all.*

I have a few similar errors for division and multipaction. I guess I'm missing an algebra?

Any guidance would be appreciated

erikerlandson commented 2 years ago

That second one should be import coulomb.ops.algebra.spire.all.given Until I write some proper tutorials, the best reference on what imports should work is probably the unit tests: https://github.com/erikerlandson/coulomb/blob/scala3/spire/src/test/scala/coulomb/quantity.scala#L20

cquiroz commented 2 years ago

Maybe it is related to Unitless. Here is a minimal reproduction

import coulomb.*
import coulomb.syntax.*

import algebra.instances.all.given
import coulomb.ops.algebra.spire.all.given

import coulomb.policy.spire.standard.given
import coulomb.units.si.*
import coulomb.units.si.given
import scala.math._

object ItcImpl2 {
  val expTime: Quantity[BigDecimal, Second]   = ???
  val nExp                                    = 1
  val totalTime: Quantity[BigDecimal, Second] =
    expTime * nExp.withUnit[Unitless]
}

With error:

[error] -- Error: /Users/carlos.quiroz/code/noirlab/lucuma-itc/modules/itc/src/main/scala/lucuma/itc/ItcImpl2.scala:22:37 
[error] 22 |    expTime * nExp.withUnit[Unitless]
[error]    |                                     ^
[error]    |Multiplication not defined in scope for Quantity[BigDecimal, coulomb.units.si.Second] and Quantity[Int, (1 : Int)]
[error]    |
[error]    |One of the following imports might make progress towards fixing the problem:
[error]    |
[error]    |  import coulomb.policy.spire.standard.ctx_mul_1V2U
[error]    |  import coulomb.policy.spire.standard.ctx_mul_2V2U
[error]    |  import coulomb.policy.spire.strict.ctx_mul_1V2U
[error]    |  import coulomb.policy.spire.strict.ctx_mul_2V2U
[error]    |  import coulomb.policy.standard.ctx_mul_1V2U
[error]    |  import coulomb.policy.standard.ctx_mul_2V2U
[error]    |  import coulomb.policy.strict.ctx_mul_1V2U
[error]    |  import coulomb.policy.strict.ctx_mul_2V2U
[error]    |  import shapeless.~?>.idKeyWitness
[error]    |  import shapeless.~?>.idValueWitness
[error]   
erikerlandson commented 2 years ago

@cquiroz I am failing to reproduce that error. I wrote this and it compiled with no errors, although it threw a bunch of warnings about Unitless being deprecated

object repro {
    import coulomb.*
    import coulomb.syntax.*

    import algebra.instances.all.given
    import coulomb.ops.algebra.spire.all.given

    import coulomb.policy.spire.standard.given
    import coulomb.units.si.*
    import coulomb.units.si.given
    import scala.math._

    object ItcImpl2 {
        val expTime: Quantity[BigDecimal, Second]   = BigDecimal(1).withUnit[Second]
        val nExp                                    = 1
        val totalTime: Quantity[BigDecimal, Second] =
          expTime * nExp.withUnit[Unitless]
    }
}
cquiroz commented 2 years ago

Thanks turns out it works when doing imports as import coulomb._ This seems to be down to a compiler issue when using a kindProjector flag

erikerlandson commented 2 years ago

@cquiroz thanks for the pointer! I will try to keep that in mind