标签: scala-3

Scala 3 (Dotty) 模式匹配带有宏引用的函数

我正在尝试通过 Scala 3.0.0-M2 中的宏获取函数名称我提出的解决方案使用 TreeAccumulator

import scala.quoted._

inline def getName[T](inline f: T => Any): String = ${getNameImpl('f)}

def getNameImpl[T](f: Expr[T => Any])(using Quotes): Expr[String] = {
  import quotes.reflect._
  val acc = new TreeAccumulator[String] {
    def foldTree(names: String, tree: Tree)(owner: Symbol): String = tree match {
      case Select(_, name) => name
      case _ => foldOverTree(names, tree)(owner)
    }
  }
  val fieldName = acc.foldTree(null, Term.of(f))(Symbol.spliceOwner)
  Expr(fieldName)
}
Run Code Online (Sandbox Code Playgroud)

调用此代码时会生成函数的名称:

case class B(field1: String)
println(getName[B](_.field1)) // "field1"
Run Code Online (Sandbox Code Playgroud)

我想知道这是否可以使用引号以更简单的方式完成。

macros scala dotty scala-macros scala-3

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

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
查看次数

?=> 在 Scala 中是什么意思?

我已经看到这个?=>符号出现在 Scala 代码和一些关于 Scala 3 的讨论帖子中,所以我假设它是一个 Scala 3+ 符号。通过文档或 Google 搜索时什么也没有出现,但它看起来像是Function类型的语法糖,所以它可能与类型和函数有关。这是什么意思?

types symbols scala function scala-3

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

Dotty 如何决定如何推断/何时扩大联合类型?

此处讨论了扩大联合类型但我似乎无法找到以下案例的答案

让我们从以下内容开始

val x = List(1, 2, "a")
Run Code Online (Sandbox Code Playgroud)

这个异构列表被推断为List[Any]就像在 Scala 2 中一样

然而以下

val x2 = List(List(1, 2), Vector("a", "b"))
Run Code Online (Sandbox Code Playgroud)

推断为 List[scala.collection.immutable.AbstractSeq[Int | String]]

这是相当混乱的行为。为什么Any在一种情况下会推断出两种不相交类型的 LUB ,而在另一种情况下会推断出联合类型?

如果这只是一个设计决定,是否有任何此类情况需要人们注意?

scala type-inference dotty union-types scala-3

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

Scala 3 中的宏注释

以下是三年多前的Macros: The Plan for Scala 3中的一段话:

例如,我们可以定义一个宏注释 @json,将 JSON 序列化器添加到一种类型中。

知道这在 Scala 3 中如何/是否可行吗?

更一般地说,Scala 3 中有什么可以提供“宏注释”功能吗?以下是宏注释 - Scala 2.13的引用:

与以前版本的宏天堂不同,2.0 中的宏注释在以下意义上是正确的:1) 不仅适用于类和对象,而且适用于任意定义,2)允许扩展类来修改甚至创建伴生对象

scala scala-macros scala-macro-paradise scala-3

7
推荐指数
2
解决办法
1071
查看次数

在运行时将 Scala 3 代码从字符串解析为 Scala 3 AST

我的目标是将 Scala 3 代码作为字符串获取,并在运行时将其解析为 Scala 3 的抽象语法树。在这个过程中,如果代码有编译错误,我应该把它作为一些异常的一部分。更大的目标是,如果 Scala 代码有效,则以 Expr[T] 结束,并通过拼接正确的位来执行它(我已经介绍了这部分)。

这在 Scala 2.* 中是可行的,在这里使用 scala-reflect 。

val source =
  """
    |object HelloWorld {
    |  def main(args: Array[String]): Unit = {
    |    println("Hello, world!")
    |  }
    |}
    |
    |HelloWorld.main(Array())
    |""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
binary()
Run Code Online (Sandbox Code Playgroud)

但据我推测,在 Scala 3 中,不会移植 scala-reflect。我如何在 Scala 3 中实现相同的目标?

这里这里的一些相关链接

reflection scala scala-3

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

Scala 3 匹配类型和 F-Bounded 类型:“无法证明”

鉴于:

abstract class Quantity[A <: Quantity[A]]
sealed trait UnitOfMeasure[A]

class Time extends Quantity[Time]
object Minutes extends UnitOfMeasure[Time]

class PowerRamp extends Quantity[PowerRamp]
object KilowattsPerHour extends UnitOfMeasure[PowerRamp]
  
type Test[X <: UnitOfMeasure[?]] = X match
  case UnitOfMeasure[t] => t
Run Code Online (Sandbox Code Playgroud)

编译如下:

summon[Test[Minutes.type] =:= Time]
summon[Test[KilowattsPerHour.type] =:= PowerRamp]
Run Code Online (Sandbox Code Playgroud)

但是,如果UnitOfMeasure声明了trait :

sealed trait UnitOfMeasure[A <: Quantity[A]]
Run Code Online (Sandbox Code Playgroud)

两次传票都失败:

Cannot prove that Test[Minutes.type] =:= Time.

Note: a match type could not be fully reduced:
  trying to reduce Test[Minutes.type]
  failed since selector Minutes.type
  matches none of the …
Run Code Online (Sandbox Code Playgroud)

scala type-level-computation scala-3

7
推荐指数
0
解决办法
84
查看次数

在 Scala 3 中将枚举(反)序列化为字符串

我试图找到一种简单而有效的方法来使用 Scala 3 来(反)序列化枚举circe

考虑以下示例:

import io.circe.generic.auto._
import io.circe.syntax._

enum OrderType:
  case BUY
  case SELL

case class Order(id: Int, `type`: OrderType, amount: String)
val order = Order(1, OrderType.SELL, "123.4")
order.asJson
Run Code Online (Sandbox Code Playgroud)

序列化数据后,它变成

{
  "id" : 1,
  "type" : {
    "SELL" : {
      
    }
  },
  "amount" : "123.4"
}
Run Code Online (Sandbox Code Playgroud)

代替

{
  "id" : 1,
  "type" : "SELL",
  "amount" : "123.4"
}
Run Code Online (Sandbox Code Playgroud)

这就是我想要的。

我知道我可以为此编写一个自定义(反)序列化器,它将解决这个特定实例的问题,如下所示:

implicit val encodeOrderType: Encoder[OrderType] = (a: OrderType) =>
  Encoder.encodeString(a.toString)
  
implicit def decodeOrderType: Decoder[OrderType] = (c: HCursor) => …
Run Code Online (Sandbox Code Playgroud)

serialization scala circe scala-3

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

从任意类型联合中类型级别删除一种类型

如果我在 Scala 3 中有一个任意类型联合,是否可以编写一个从联合中“删除”一种类型的方法?

与 类似shapeless.ops.coproduct.Remove,但适用于本机 Scala 3。

例如,如果我有一个代表一些不同错误的联合类型,并且我想编写一个从一种特定错误类型中恢复的函数,并将其余错误保留为新的联合类型。

val result: Either[Foo | Bar | Baz | Bang, Thing]
val otherResult: Either[Foo | Bar, OtherThing]

// pretend syntax
def recoverBar[X, A](error: Bar | ...X)(f: Bar => A): Either[X, A] = 
  error match {
    case e: Bar => Right(f(e))
    case otherError => Left(otherError)
  }

// example usage
val recoveredResult: Either[Foo | Baz | Bang, Option[Thing]] = result
  .map { Option.apply }
  .left.flatMap { recoverBar(_)(_ => None) }

val recoveredOther: …
Run Code Online (Sandbox Code Playgroud)

scala type-level-computation scala-3

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

Scala 中的“prolog 风格”是什么?

https://docs.scala-lang.org/scala3/reference/metaprogramming/compiletime-ops.html上的 Scala 3 参考文献提到了 Scala 3 mataprogramming 可能实现的一些“类似 Prolog 的编程风格”:

到目前为止的问题是,类似于 Prolog 的隐式搜索编程风格变得病毒式传播:一旦某个构造依赖于隐式搜索,它就必须被编写为逻辑程序本身。

但它们都保留了基于逻辑编程的隐式搜索程序的病毒性。

我做了一些搜索,但只知道它在某种程度上滥用了 Scala 编译时行为,并且其中的某些内容类似于 Prolog。

什么是“类似 Prolog 的编程风格”以及它是如何工作的?什么类似于Prolog?它在 Scala 3 中有效吗?

scala prolog implicit scala-3

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