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/