This code works - I can parse an empty string into Option[Int] as None:
trait Field[T]:
def parse(s:String):T
object Field:
given Field[Int] with
def parse(s:String) = s.toInt
given Field[Boolean] with
def parse(s:String) = s.toBoolean
given Field[Double] with
def parse(s:String) = s.toDouble
given Field[Option[Int]] with
def parse(s:String):Option[Int] = if s.length > 0 then Some(s.toInt) else None
/* CANNOT DO THIS!
given Field[Option[Double]] with
def parse(s:String):Option[Double] = if s.length > 0 then Some(s.toDouble) else None
,*/
def fromString[T: Field](s:String):T =
summon[Field[T]].parse(s)
val args = Seq("123", "true", "7.5", "", "")
val myInt = fromString[Int](args(0))
val myBoolean = fromString[Boolean](args(1))
val myDouble = fromString[Double](args(2))
val myOptionInt = fromString[Option[Int]](args(3))
/* CANNOT DO THIS!
val myOptionDouble = fromString[Option[Double]](args(4))
*/
println(myInt)
println(myBoolean)
println(myDouble)
println(myOptionInt)
/* CANNOT DO THIS!
println(myOptionDouble)
*/
But I cannot extend idea to Option[Double] because type erasure disallows compiler to recognize both Int and Double in Option[T] - type erasure means at runtime Option[Int] and Option[Double] cannot be distinguished (I think)?
given Field[Option[Double]] with
^
given_Field_Option is already defined as object given_Field_Option
def parse(s:String):Option[Double] = if s.length > 0 then Some(s.toDouble) else None
Compilation failed
How to get around this in Scala 3 and have type class work with both Option[Int] and Option[Double]?