Hey!
I have the following code:
type Size = "single" | "optional" | "many"
type Out[S <: Size, A] =
S match
case "single" => A
case "optional" => Option[A]
case "many" => List[A]
trait Runner[S <: Size, A]:
def input: A
inline def run: Out[S, A] =
inline erasedValue[S] match
case _: "single" =>
mkSingle(input)
case _: "optional" =>
mkOption(input)
case _: "many" =>
mkList(input)
It works awesome and user of the Runner
trait always gets the output type they need.
All above mk-functions accept the same type A
and everything works fine. But now I change their signature and want for example that mkSingle
accepted Boolean
and thus my A
becomes Boolean
if and only if the S
is “single”:
type MkInput[S <: Size, A] =
S match
case "single" => Boolean
case "optional" => A
case "many" => String
trait Runner[S <: Size, A]:
inline def run(input: MkInput[S, A]): Out[S, A] =
inline erasedValue[S] match
case _: "single" =>
mkSingle(input) // Now all mk-functions are different now
case _: "optional" =>
mkOption(input)
case _: "many" =>
mkList(input)
This code doesn’t however, although I expect it should - the S
type is shared between MkInput
and Out
, hence we always know upfront that mkSingle
or mkOption
gets the expected type. However I’m getting the following error, indicating that match types are not expanded on argument position:
[error] 132 | mkOption(input)
[error] | ^^^^^
[error] |Found: (input : io.foldables.ratio.queries.Action.MkInput[S, A])
[error] |Required: Boolean
[error] |
[error] |where: S is a type in method foo with bounds <: io.foldables.ratio.queries.Action.Size
Is there a way to proove the compiler that my input
is of proper type?