Search code examples
scalascala-macrosscala-3

Scala 3 : Create Expr[ Int => Int ]


I am using Scala3 macros in a project and I am stuck at creating Expr (and ToExpr) of a function.

I have something like this :

case class Foo(f : Int => Int)

given ToExpr[Foo] with {
    def apply(foo : Foo) = foo match {
        case Foo(f) => '{Foo(???)} // <-- here
    }
}

I can't figure out how to have an Expr[Int => Int] to replace ??? above.


EDIT: here are some failed attempts by @GaelJ

1) First try

def apply(foo : Foo) = foo match {
  case Foo(f) =>
    val ff: Expr[Int => Int] = '{ (x: Int) => f.apply(x) }
    '{Foo($ff)}
}

Gives:

|        val ff: Expr[Int => Int] = '{ (x: Int) => f.apply(x) }
|                                                  ^
|                             access to value f from wrong staging level:
|                              - the definition is at level 0,
|                              - but the access is at level 1.

2) Second try

def apply(foo : Foo) = foo match {
  case Foo(f) =>
    val ff: Expr[Int => Int] = '{ (x: Int) => ($f).apply(x) }
    '{Foo($ff)}
}

Gives:

|        val ff: Expr[Int => Int] = '{ (x: Int) => ($f).apply(x) }
|                                                    ^
|                                              Found:    (f : Int => Int)
|                                              Required: quoted.Expr[Any]

Solution

  • Here are the given "build blocks" to construct new ToExpr : scala3 docs ToExpr. From what I see it is not possible to construct a ToExpr for a function.