微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

扩展依赖类型

如何解决扩展依赖类型

这是我的问题的最小再现:

  trait Superclass[T]
  
  class A(val key: Any) extends Superclass[key.type]
  
  val x: Superclass["123"] = A("123")

如您所见,我正在尝试将静态已知的Key类型编码为type参数。 并不是说我可以将key的类型作为A的类型参数,因为在我的实际示例中,它更像class A(using g: blablah)(val key: g.Key) extends SuperClass[g.Mapping[key.type]],但这与上面的问题无关。

难道我们不能在超类的参数内使用依赖类型吗?

更新

使用类型成员进行编码会产生相同的错误

  trait Superclass {
    type T
  }
  
  class A(val key: Any) extends Superclass {
    type T = key.type
  }
  
  val x: Superclass & {type T = "123"} = A("123")

我仍然得到

[error] 14 |  val x: Superclass & {type T = "123"} = A("123")
[error]    |                                         ^^^^^^^^
[error]    |                Found:    Main.A
[error]    |                required: Main.Superclass & Object{T = ("123" : String)}

解决方法

我无法解决您给出的示例,但这可能适合您的实际用例。

trait Superclass[T]

//The type of G
trait Foo:
  type Key
  type Mapping[K <: Key]

class A [K,KT <: K,M[_ <: K],G <: Foo {type Key = K; type Mapping[T <: K] = M[T]}] private(val key: KT,g: G)
    extends Superclass[M[KT]]

object A:
  def apply[G <: Foo](using g: G)(key: g.Key) =
     new A[g.Key,key.type,g.Mapping,g.type](key,g)

您可以像这样使用它:

class FooImpl extends Foo:
  type Key = String
  type Mapping[S <: String] = List[S]

given myG as FooImpl = FooImpl()

val x: Superclass[List["123"]] = A[FooImpl]("123")

Foo中,Key用于绑定可以赋予Mapping的键。类K上的A参数是key的类型的上限,而KT是密钥的实际类型。 M代表Mapping。我使用类型细化是因为类型投影不健全,已在Scala 3中删除。

为方便起见,您可以向apply的同伴中添加A方法,并将A自己的构造函数设为私有。

看到它在Scastie中运行。

关于构造函数中的依赖类型,请参见this issue。看来您无法像在方法中那样使用它们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。