While testing some code that I recently created i figured that some passages are not compiling without explicit type annotation. I tried to minimize the problem in the following code snippet:
case class Base[E,S](al:Set[E],sts:Set[MidState[S]],ss:MidState[S],
d:Map[(MidState[S],E),MidState[S]],aS:Set[MidState[S]])
case class Edge[E,S](state_1: MidState[S],l:E ,state_2: MidState[S])
sealed trait MidState[S] extends BaseState[S]
sealed case class State[S](l:S)
extends MidState[S]
case object FailureState extends MidState[Nothing]
Base has a companion object with an apply method defined as follows:
object Base {
def apply [E,S](edges:Set[Edge[E,S]],ss:MidState[S],
aS:Set[MidState[S]],partialMode:Boolean): Base[E,S]
When i am trying to instantiate Base with this apply method i cannot get around an explicit type annotation for aS:
val aS : Set[MidState[String]] = (State("C") :: Nil).toSet
val base = Base(edges,State("A"),aS,partialMode = true)
If i erase the explicit type annotation for aS, aS is of type Set[State[S]] and not Set[MidState[S]] which it needs to be for the apply method. Is there any better solution to avoid this explicit type annotation despite inserting (State("C") :: Nil).toSet directly into the apply method?
The first thing you could do is to remove all the :: Nil
and .toSet
and : ...
noise:
val aS = Set[MidState[String]](State("C"))
This is actually quite common: for example, it frequently occurs as the first argument in fold
s, where one has to explicitly write Set[Int]()
or Set.empty[Int]
in order to get the types right.
If this is still too noisy, just add appropriate factory methods to MidState
:
object MidState {
def apply[S](s: S): MidState[S] = State(s)
}
and then invoke the factory method that constructs the right type of object right away:
val bS = Set(MidState("C"))