-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
Compiler version
3.1.2
Minimized code
enum Format[A]:
case Str[Next](next: Format[Next]) extends Format[(String, Next)]
case Num[Next](next: Format[Next]) extends Format[(Int, Next)]
case Constant[Next](value: String, next: Format[Next]) extends Format[Next]
case Done extends Format[Unit]
def printf[A](format: Format[A], params: A): Unit = (format, params) match
case (Format.Done, ()) =>
()
case (Format.Constant(value, next), params) =>
println(value)
printf(next, params)
case (Format.Str(next), (str, rest)) =>
println(str)
printf(next, rest)
case (Format.Num(next), (i, rest)) =>
println(i)
printf(next, rest)
Output
Compilation failure, the compiler cannot convince itself that, in the Format.Str
branch, for example, A
is of type (String, ...)
(where ...
is the right type to pass to next
).
Expectation
This should compile: the compiler already knows the right types. As shown by @smarter , the following code compiles (and runs as expected):
enum Format[A]:
case Str[Next](next: Format[Next]) extends Format[(String, Next)]
case Num[Next](next: Format[Next]) extends Format[(Int, Next)]
case Constant[Next](value: String, next: Format[Next]) extends Format[Next]
case Done extends Format[Unit]
def printf[A](format: Format[A], params: A): Unit = format match
case Format.Done =>
()
case Format.Constant(value, next) =>
print(value)
printf(next, params)
case Format.Str(next) =>
print(params(0))
printf(next, params(1))
case Format.Num(next) =>
print(params(0))
printf(next, params(1))
Note that the only difference is, instead of pattern matching on the tuple, this code explicitly calls apply
on it, which somehow satisfies the compiler that everything is alright.
dwijnand, diesalbla and Linyxus