val WIDTH: W = ...
val x_resolution: W = ...
val HEIGHT: H = ...
val y_resolution: H = ...
warnNotInteger("Number of vertical stripes not integer:", WIDTH, x_resolution, total_vertical, wf)
warnNotInteger("Number of horizontal stripes not integer:",HEIGHT, y_resolution, total_horizontal, hf)
warnNotInteger("Number of horizontal stripes not integer:",HEIGHT, x_resolution, total_horizontal, hf)
How can one ensure the last call above does not compile? In other words T must either be an H or a W.
How the compiler “thinks”: if type parameters are not given explicitly, try fill in the type automatically by searching for most specific type that conforms - relax to more general types if needed and if no other type works try with most general type Any.
If you provide a type parameter, as recommended by @spamegg1, you “nail the type to the floor”, meaning that this will be a hard requirements on the type constraint problem that the compiler is trying to solve. If the problem is not solvable (i.e. you have provided inconsistent type constraints) then you will get a compile error. Which is good if this detects an error. Less bugs! THANK YOU compiler!
@spamegg1 Unfortunately I neglected to mention an important point: type W and H are of the same primitive type. I have declared these as opaque types. They server “only” to ensure that the correct parameters are used at the call site. My apologies.
@bjornregnell As I explained to @spamegg1, the problem is that H and W has the same primitive type. I will have to give some more thought to the use of inheritance. This may work although for more than 2 classes this may be convoluted.
Perhaps you could wrap them into something similar to:
def resolution(w: Width, h: Height): Option[(Int, Int)] = ???
trait Dim:
case class Width(w: Double) extends Dim
case class Height(h: Double) extends Dim
Or using enums:
enum Dim:
case Width(w: Double)
case Height(h: Double)
Thanks for all the suggestions. I came up with the “solution” below (single definition but multiple type parameters). It works with opaque types (no expensive wrapping) that use the same primitive type and fails with different primitive opaque types.