Hello,
I’ve been trying out new features in Scala 3 for a while, but I’ve got some questions:
- is it possible to create a contextual function with anonymous function, i.e.
val f: Int ?=> Unit = (using x: Int) => ()
- is it possible to overload a method with different context, i.e.
def f(using x: Something) = ??? def f(using x: NotGiven[Something]) = ???
Thank you
Yes. You can choose between these 2:
val f: Int ?=> Unit = (x: Int) ?=> println(x)
val g: Int ?=> Unit = println(summon[Int])
Not really. You can define them, but if you try to call them the compiler won’t choose a method based on the available context or givens. You’ll probably get an ambiguous overload error instead. You could use a different approach.
enum MaybeGiven[+A]:
case Some(a: A)
case None
object MaybeGiven:
given [A](using A): MaybeGiven[A] = Some(summon[A])
given [A](using NotGiven[A]): MaybeGiven[A] = None
def f(using maybe: MaybeGiven[Something]) =
maybe match
case MaybeGiven.Some(x) => ???
case MaybeGiven.None => ???
1 Like
@Jasper-M Thank you for your help.
The MaybeGiven
solution seems to be a useful pattern. Maybe it should be baked into the standard library.
@Jasper-M
On second thought, it seems that the f: MaybeGiven[Something] ?=> T
seems can only have one fixed return type.
What I was thinking was actually the builder pattern that was given in the scala 3 document:
def table(init: Table ?=> Unit) =
given t: Table = Table()
init
t
def row(init: Row ?=> Unit)(using t: Table) =
given r: Row = Row()
init
t.add(r)
def cell(str: String)(using r: Row) =
r.add(new Cell(str))
It’s evident that the outmost function does not use using
and returns something while the inner function use using
and returns Unit
. I was thinking if we can overload them to one function such that we can just do:
table { table { table { } } }
for example. This requires that the function being overloaded with different return type. But it seems impossible?