I am learning scala3 given and using usage, and have a following code
package sample
trait A[T]:
def f(f: => T): T
given instance (using depX: X): A[TypeV] with
def f(f: => TypeV): TypeV = depX.method1(f)
Now I want to use this instance in main function. How should I instantiate and use it?
I tried defining with
package sample
object A:
def f(f: => TypeV)(using i: instance): TypeV = i.f(f)
and in another scala file
package
import sample.{using, ?, *}
@main def execute = A.f("hi")
But this will give “no implicitly type of argument … was found for parameter i of method f in object A”
If I pass with A.f("hi")(summon[Instance])
the error remains the same.
What is the right way to instantiate and call the given instance?
I use scala 3.0.1 and java 11.0.12
Thanks.
Ok I suppose I know how it works now.
trait A[T]:
def f(f: => T): T
object A:
def apply[T: A](): A[T] = summon[A[T]]
given insA: A[String] = new A[String] {
def f(f: => String): String = {println(f); f}
}
@main def execute(): Unit = {
given instance: A[String] = insA
val runtimeA = A()
runtimeA.info("hi!")
}
Thanks
As you already found out, using def apply[T: A]()
works (which is a context bound).
The reason your previous attempt with (using i: instance)
did not work is, that given
and using
lookups work by type, so you would need to write (using i: A[TypeV])
instead. Names of instances are only relevant for imports and for explicitly passing them instead of letting the compiler look them up, which is why Scala 3 even makes them optional.
In your main method, you should not have to declare another given
, which just aliases the already defined instance, an import should do it. Note that you’d have to use import sample.given
to import the given instances in the package sample
.
1 Like
Thanks for the explanation. That’s helpful! I also find this doc[1], that helps me understand the usage better. Thank you!
[1]. https://blog.knoldus.com/an-introduction-to-givens-in-scala-3/