trait ToResponseCode[A]:
def toResponseCode: Boolean
given ToResponseCode[Int]:
def toResponseCode = false
trait ToJSON[A]:
def encode(a: A): String
given ToJSON[Boolean]:
def encode(a: Boolean) = a.toString
val responseCode: ToResponseCode[Int] =
summon
scala[error] 14 | summon
[error] | ^
[error] |ambiguous implicit arguments: both object given_ToResponseCode_Int and method given_ToJSON_Boolean match type T of parameter x of method summon in object DottyPredef
Should be able to assign the type in summon without it being explicitly annotated.
Replacing summon by implicitly or by summon[ToResponseCode[CREATED[JSON, Int]]] works. This example can probably be minimized further.
I minimized it further 鈽濓笍
can do this too:
given as Int = 0
given as Boolean = true
val r: Int = summon
That looks a lot more minimized 馃槀
It's the price we pay to have summon defined like this:
inline def summon[T](using x: T): x.type = x
Upside: summon can refine the expected type, just like the the in Shapeless does.
Downside: We can't constrain using the expected type, so summon has to come with a type parameter.
I think the price is worth paying. If one does not want it, one can use implicitly. or a home-brewed alternative:
inline def implicitly[T](using x: T): T = x
Cool, any reason not to have implicitly be an inline def moving forward?
Theoretically it may be possibly constrain T, given that we know that T >: x.type <: Int, and we don't know x.type, therefore T <: Int?