相关疑难解决方法(0)

如何在dotty宏中访问case类的参数列表

我正在尝试在 dotty 中学习元编程。具体编译时间代码生成。我认为通过构建一些东西来学习是一种很好的方法。所以我决定制作一个 CSV 解析器,它将行解析为案例类。我想使用dotty宏来生成解码器

trait Decoder[T]{
  def decode(str:String):Either[ParseError, T]
}

object Decoder {
  inline given stringDec as Decoder[String] = new Decoder[String] {
    override def decode(str: String): Either[ParseError, String] = Right(str)
  }

  inline given intDec as Decoder[Int] = new Decoder[Int] {
    override def decode(str: String): Either[ParseError, Int] =
      str.toIntOption.toRight(ParseError(str, "value is not valid Int"))
  }
  
  inline def forType[T]:Decoder[T] = ${make[T]}

  def make[T:Type](using qctx: QuoteContext):Expr[Decoder[T]] = ???
}
Run Code Online (Sandbox Code Playgroud)

我已经为Int&提供了基本的解码器String,现在我正在寻找def make[T:Type]方法的指导。如何T在此方法中迭代案例类的参数列表?有没有推荐的方法或模式来做到这一点?

reflection scala metaprogramming dotty scala-macros

8
推荐指数
1
解决办法
741
查看次数

scala 3 宏如何实现通用特征

我想实现proxy一些特征A(例如委托方法调用到一些 rpc 调用),像这样

   def clientProxy[A](using Type[A], Quotes): Expr[A] = {
    import quotes.reflect._
    val defTrees: List[Tree] = TypeRepr.of[A].typeSymbol.memberFields.collect {
      case mf if mf.isDefDef =>
        ???
    }

    val exprs = Expr.ofList(defTrees.map(_.asExpr))
    '{
      new A {
        $exprs
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

但是编译器抱怨

A is not a class type

Run Code Online (Sandbox Code Playgroud)

scala dotty scala-3

8
推荐指数
1
解决办法
165
查看次数

如何使用宏在 Dotty 中生成一个类?

是否可以在 Dotty, Scala 3 中生成一个带有宏的新类?

兹拉亚

annotations scala metaprogramming dotty scala-macros

6
推荐指数
2
解决办法
729
查看次数

如何在 Scala 3 宏中创建泛型类型的实例?

我正在将宏从 Scala 2 移植到 Scala 3。作为其工作的一部分,Scala 2 宏使用默认构造函数创建泛型类型的实例。在 Scala 2 中使用准引用很容易做到这一点,但我在 Scala 3 宏上遇到了困难。这是迄今为止我最好的方法:

import scala.quoted.*

inline def make[A <: AnyRef]: A = ${ makeThat[A] }

private def makeThat[A <: AnyRef : Type](using Quotes): Expr[A] =
  import quotes.reflect.*

  '{ new A().asInstanceOf[A] }
Run Code Online (Sandbox Code Playgroud)

如果没有.asInstanceOf[A],编译器会发出错误消息:

[error] -- [E007] Type Mismatch Error: ...
[error] 17 |  '{ new A() }
[error]    |     ^^^^^^^
[error]    |Found:    Object
[error]    |Required: A
[error]    |
[error]    |where:    A is a type in method makeThat with …
Run Code Online (Sandbox Code Playgroud)

scala metaprogramming scala-macros scala-3

6
推荐指数
1
解决办法
501
查看次数

Scala3:通过元编程创建类型?

我正在使用 scala3 进行编码,利用编程结构类型。结构类型恰好模仿了现有的案例类:它们的定义是纯粹的样板,因此很容易通过元编程来制作它们。

我了解如何制作函数实现,通常是通过类型类派生。但在这里我们正在尝试制作一个(结构)类型

这在 scala2 中是可能的,通过类宏注释,但这些在 scala3 中已经消失了。有办法吗?如果是这样怎么办?

下面的代码是我想获得的结果:


// Library part
trait View extends scala.Selectable :
  def selectDynamic(key:String) =
    println(s"$key is being looked up")
    ???


// DSL Definition part
case class SomeDefWithInt   ( i : Int    )
case class SomeDefWithString( s : String )

// Boiler-plate code 
type ViewOf[M] = M match
  case SomeDefWithInt    => View { def i : Int    }
  case SomeDefWithString => View { def s : …
Run Code Online (Sandbox Code Playgroud)

scala metaprogramming scala-macros scala-3

3
推荐指数
1
解决办法
610
查看次数

Scala 3 宏中的“tq”等效项

使用 Scala2,我可以实现宏并使用tq准引用语法生成类型,例如:

q"""        
new Foo {
  type Bar = ${tq"(..$params)"}
}
"""
Run Code Online (Sandbox Code Playgroud)

我可以用这种语法做两件事 -

  1. 能够Bar基于params.
  2. 能够将 作为元组传播params

如何使用 Scala 3 实现这一目标?

scala scala-macros scala-quasiquotes scala-3

1
推荐指数
1
解决办法
293
查看次数