我是 Gradle 和 Dotty 的新手(而且对 Scala 整体来说仍然相对较新)。我能够像这样用 Gradle 创建一个 Scala 项目:
gradle init --dsl kotlin --type scala-library --package com.stackoverflow.example
Run Code Online (Sandbox Code Playgroud)
而且我知道 Dotty 可以与 SBT 一起使用。但是有没有办法将 Dotty 与 Gradle 连接起来(还)?
我有以下场景:
case class B(v: String)
case class A(bs: Seq[B])
extension(a: A)
def doit() = a.bs.map(_.doit()) // here is the exception
extension(b: B)
def doit() = println("OK: ${b.v}")
Run Code Online (Sandbox Code Playgroud)
这给了我以下编译异常:
value doit is not a member of B.
An extension method was tried, but could not be fully constructed:
_$1
Run Code Online (Sandbox Code Playgroud)
Scala 3中扩展方法的命名有限制吗?
请参阅Scastie上的示例
我正在将宏从 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) 以下代码的输出只是list(没有打印数字)。
trait TC[A]:
inline def show(value: A): Unit
object TC:
given TC[Int] with
inline def show(value: Int): Unit = println(value)
given[A:TC]: TC[List[A]] with
inline def show(value: List[A]): Unit =
println("list")
value.foreach(x => summon[TC[A]].show(x))
@main
def main: Unit =
import TC._
val value = 1 :: 2 :: 3 :: Nil
summon[TC[List[Int]]].show(value)
Run Code Online (Sandbox Code Playgroud)
如果我删除,inline那么一切都会好起来的。我是否在调用未定义的行为?
在 Scala 3 中summon似乎和旧的implicitly. 但是当我们深入研究实际例子时,我们发现情况并非如此。例如
case class A(i: Int, s: String)
val mirror = implicitly[Mirror.Of[A]]
type ValueOfs = Tuple.Map[mirror.MirroredElemLabels, ValueOf]
val valueOfs = summonAll[ValueOfs]
def values(t: Tuple): Tuple = t match
case (h: ValueOf[_]) *: t1 => h.value *: values(t1)
case EmptyTuple => EmptyTuple
Run Code Online (Sandbox Code Playgroud)
产生错误
cannot reduce inline match with
scrutinee: compiletime.erasedValue[App.ValueOfs] : App.ValueOfs
patterns : case _:EmptyTuple
case _:*:[t @ _, ts @ _]
Run Code Online (Sandbox Code Playgroud)
但是替换implicitly[Mirror.Of[A]]为summon[Mirror.Of[A]]编译很好。
在这种情况下和一般情况下summonvs的微妙之处是什么implicitly?
想要这样做的特殊原因是仍然能够对来自超类的值使用模式匹配。例如,我希望case None在查看 type 的值时能够匹配Option[Throwable],但这似乎不可能,因为Throwable不可能,而且(我想)永远不会有CanEqual实例。
给定以下枚举:
enum Connector:
case CHAdeMO
case Mennekes
case CCS
case Tesla
Run Code Online (Sandbox Code Playgroud)
是否有类似Map[ConnectorType, Int]但会产生编译错误的类型:
Map(
Connector.CHAdeMO -> 1,
Connector.Mennekes -> 2,
Connector.CCS -> 3,
)
Run Code Online (Sandbox Code Playgroud)
也就是说,地图不包含 的键Connector.Tesla。换句话说,在编译时,类型应该类似于((Connector.CHAdeMO, Int), (Connector.Mennekes, Int), (Connector.CCS, Int), (Connector.Tesla, Int))常规 Map,但在其他方面表现得像常规 Map。
我在 Scala 3 中定义了以下特征:
\ntrait A[T <: Tuple]\nRun Code Online (Sandbox Code Playgroud)\n然后,我使用 Scala 3 宏创建具有此特征的对象,对元组的实际类型执行进一步检查T;特别是,我想检查元组的所有类型(T_1,\xe2\x80\xa6,T_n)T是否是另一个给定类型的子类型B:
trait B\nprivate def allSubtypesOfB[T <: Tuple: Type](using quotes: Quotes): Boolean = {\n import quotes.reflect.*\n case '[Nothing] => false // I don't want nothing to be in T\n case '[head *: tail] if TypeRepr.of[head] <:< TypeRepr.of[B] => allSubtypesOfB[tail]\n case '[EmptyTuple] => true\n case _ => false\n}\n\ninline def createA[T <: Tuple] = ${ createAImpl[T] }\nprivate def createAImpl[T …Run Code Online (Sandbox Code Playgroud) 假设我想使用这样的匹配类型来表示一个向量:
\ntype V[I <: Int, N] = I match\n case 2 => (N, N)\n case 3 => (N, N, N)\n case 4 => (N, N, N, N)\nRun Code Online (Sandbox Code Playgroud)\n所以现在我可以使用元组声明我的向量:
\n val v2: V[2, Int] = (2, 2)\n val v3: V[3, Int] = (3, 3, 3)\n val v4: V[4, Int] = (4, 4, 4, 4)\nRun Code Online (Sandbox Code Playgroud)\n然后我可以定义一个元组矩阵和一个元组方阵:
\ntype Mx[L <: Int, C <: Int, N] = V[L, V[C, N]]\ntype Mxq[T <: Int, N] = Mx[T, T, N]\ntype M3I = …Run Code Online (Sandbox Code Playgroud) 我正在尝试将库从 Scala 2.13 迁移到 Scala 3,但现有代码无法编译。
这是一个片段
trait Identity
trait Authenticator
trait Env {
type I <: Identity
type A <: Authenticator
}
trait IdentityService[T <: Identity]
trait AuthenticatorService[T <: Authenticator]
trait Environment[E <: Env] {
def identityService[T <: Identity]: IdentityService[E#I]
def authenticatorService: AuthenticatorService[E#A]
}
Run Code Online (Sandbox Code Playgroud)
Scala 3 编译器失败并显示:
error] 14 | def identityService[T <: Identity]: IdentityService[E#I]
[error] | ^
[error] | E is not a legal path
[error] | since it is not a concrete type
[error] -- Error:
[error] …Run Code Online (Sandbox Code Playgroud) scala ×10
scala-3 ×10
dotty ×2
scala-macros ×2
generics ×1
gradle ×1
gradle-scala ×1
implicit ×1
match-types ×1
tuples ×1
typeclass ×1