I have an decoder that uses implicit resolution to convert a type I to a type O (see code below, also available here). During conversion I do:
val t1 = convertX[Int, Type1](1)
However, I would like to have that call use only one of the types (only one possible mapping):
val t1 = convertX[Int](1)
Is this possible? Tried using typed lambdas but I cannot figure out what lambda should go were.
TIA
trait DecoderX[I,O]:
def decode(a: I): O
case class Type1(int: Int)
case class Type2(str: String)
object DecoderX:
given DecoderX[Int, Type1] with
def decode(x: Int) = Type1(x)
given DecoderX[String, Type2] with
def decode(x: String) = Type2(x)
def convertX[I, O](in: I)(using DecoderX[I,O]): O =
val decoder = summon[DecoderX[I,O]]
decoder.decode(in: I)
import DecoderX.{*, given}
val t1 = convertX[Int, Type1](1)
However, I was under the impression that such a trick should not be needed anymore in Scala 3 thanks to features like context functions, and polymorphic functions… But I am not sure how exactly to join both to get the same effect.
It would be great if someone can show what would be the idiomatic way to solve this in Scala 3.
If I understand you correctly, you want to specify the input type, as you do in your example, and there should only be one given Decoder instance per input type, correct?
For that, I’d suggest changing the Decoder trait to use a type member:
trait DecoderX[I]:
type O
def decode(a: I): O
object DecoderX:
given DecoderX[Int] with
type O = Type1
def decode(x: Int) = Type1(x)
You can then define the convertX method as follows:
This will allow you to specify only the input type, or in case of your example even no type at all (1 can be inferred to Int):
val t1 = convertX(1)
If you want to specify the output type of the conversion instead, it is possible without changing the trait, but with a slightly different call-site signature:
def convertX[I](in: I) =
[O] => (decoder: DecoderX[I,O]) ?=> decoder.decode(in)
// when calling, needs type *after* other parameter
val t1 = convertX(1)[Type1]
@crater2150 Nice. The version that uses the context function (convertX2 in the link) is what I am looking for (just as @BalmungSan had suggested). It provides the full type. Got to chew on this for a while