units
units copied to clipboard
DoubleU[/[O,I]#Mul[I]] not being treated as Double[O]
def linear[I <: MUnit,O <: MUnit](n: String, offset: DoubleU[O], coef: DoubleU[O / I]) =
Sensor.Invertible[I,O](n, i => offset + coef * i, o => (o - offset) / coef)
Produces:
[error] overloaded method value + with alternatives:
[error] (i: DoubleU[O])DoubleU[O] <and>
[error] (i: IntU[O])DoubleU[O]
[error] cannot be applied to (DoubleU[/[O,I]#Mul[I]])
[error] Sensor.Invertible[I,O](n, i => offset + coef * i, o => (o - offset) / coef)
[error] ^
Is that sort of type-arithmetic even possible in Scala? I'm guessing not, but had to ask.
No, sadly Scala is not that smart. Maybe type macros could help, but I don't think they're done yet, and also I'm not a macro guru.
You can either:
-
cast explicitly, losing type safety
-
add
(impicit ev: (O/I)#Mul[I] =:= O)
to the parameters: it's ugly, it needs you to get the aforementioned compilation error first, and won't work in any more complicated case -
use explicit polymorphism using Systems, but that's a lot of work:
type Input = DefineType[_I] type Output = DefineType[_O] def linear(n: String, offset: DoubleU[Output], coef: DoubleU[Output / Input]) = ....... (...) val X = System2[Input, second, Output, milimetre] val X(result) = linear("string", X(offset), X(coeff)) //result is in mm
https://github.com/KarolS/units/blob/master/doc/POLYMORPHISM.md
You could also normalize the result type multiplication based on the input parameter types. That would require some implicits, depend path and would make the code much more complicated. It would be also necessary to think about what is normalized representation of units should look like.