Scala style guides tend to carry more than a few silly and counterproductive suggestions. As such, I limit the kinds of expressions I strongly suggest to those with specific semantic consequences. This sort of “ritual” appears to just be stylish, but turns out to be meaningful in the language.
For example, v: Ty
in a pattern is not an annotation. You can easily see this happen, getting an error at runtime for what appears to be a type error here:
def boom(yes: Boolean) = {
val (s: String, i: Int) = if (yes) (42, "hi") else ("hi", 42)
s.length + i
}
scala> boom(false)
res0: Int = 44
scala> boom(true)
scala.MatchError: (42,hi) (of class scala.Tuple2)
at .boom(<console>:12)
It is safer to write nothing at all than to write a type pattern. If I remove : String
and : Int
, I get a compile-time error for the same code:
scala> def boom(yes: Boolean) = {
val (s, i) = if (yes) (42, "hi") else ("hi", 42)
s.length + i
}
<console>:13: error: value length is not a member of Any
s.length + i
^
This applies to case
s, too; there is nowhere in the case
syntax for annotations, anything that looks like one is actually a type pattern.
The fix here is to move the types to the part of the val
that is actually meant for annotations:
scala> def boom(yes: Boolean) = {
val (s, i): (String, Int) = if (yes) (42, "hi") else ("hi", 42)
s.length + i
}
<console>:12: error: type mismatch;
found : Int(42)
required: String
val (s, i): (String, Int) = if (yes) (42, "hi") else ("hi", 42)
^
And now we get the proper error from a proper annotation.
Adapted from an earlier Slack thread; tested with Scala 2.12.11.