首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在构造函数中实现参数化和路径依赖型参数化?

如何在构造函数中实现参数化和路径依赖型参数化?
EN

Stack Overflow用户
提问于 2019-08-02 12:37:32
回答 1查看 119关注 0票数 1

(使用scala 2.11.12)

这为什么要编译呢?

代码语言:javascript
复制
  sealed trait Inner

  sealed trait Outer {
    sealed trait I extends Inner
  }

  case object OuterA extends Outer {
    case object Inner1 extends I
    case object Inner2 extends I
  }

  case object OuterB extends Outer {
    case object Inner1 extends I
  }

  class Data[O <: Outer](outer: O, inner: O#I)
  // I expected this not to compile but it actually does
  val data = new Data(OuterA, OuterB.Inner1)

为什么这不编译?

代码语言:javascript
复制
  sealed trait Inner

  sealed trait Outer {
    type I <: Inner
  }

  case object OuterA extends Outer {
    sealed trait OuterAInner extends Inner
    override type I = OuterAInner
    case object Inner1 extends OuterAInner
    case object Inner2 extends OuterAInner
  }

  case object OuterB extends Outer {
    sealed trait OuterBInner extends Inner
    override type I = OuterBInner
    case object Inner1 extends OuterBInner
  }

  class Data[O <: Outer](outer: O, inner: O#I)
  // I expected this to compile but it actually does not
  val data = new Data(OuterA, OuterA.Inner1)
  // type mismatch;
  //   found   : com.transparencyrights.ermine.model.V1.OuterA.Inner1.type
  //   required: ?#I
  //  Note that Inner1 extends Any, not AnyRef.
  //  Such types can participate in value classes, but instances
  //  cannot appear in singleton types or in reference comparisons.
  //    val data = new Data(OuterA, OuterA.Inner1)

我想要实现的是一个唯一的Data构造函数,它包含两个参数,一个Outer和一个InnerInner类型仅限于依赖于给定Outer实例的Inner子类型。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-02 14:32:34

在这两种情况下,问题都是O#I没有按照您的要求来做。

它实际上并不是指您所拥有的特定O中的O,而是指Outer中的通用O

可以使用路径依赖类型通用类型约束修复这两个片段。

案例1

代码语言:javascript
复制
sealed trait Inner

sealed trait Outer {
  sealed trait I extends Inner
}

final case object OuterA extends Outer {
  final case object Inner1 extends I
  final case object Inner2 extends I
}

final case object OuterB extends Outer {
  final case object Inner1 extends I
}

final class Data[O <: Outer, I <: O#I] private (outer: O, inner: I)

object Data {
  final def apply[O <: Outer, I <: O#I](outer: O, inner: I)(implicit ev: I <:< outer.I): Data[O, I] =
    new Data(outer, inner)
}

val data = Data(OuterA, OuterB.Inner1) // Does not compile.
val data = Data(OuterA, OuterA.Inner1) // Does compile.

案例2

代码语言:javascript
复制
sealed trait Inner

sealed trait Outer {
  type I <: Inner
}

final case object OuterA extends Outer {
  override final type I = OuterAInner

  sealed trait OuterAInner extends Inner

  final case object Inner1 extends OuterAInner
  final case object Inner2 extends OuterAInner
}

final case object OuterB extends Outer {
  override final type I = OuterBInner

  sealed trait OuterBInner extends Inner

  final case object Inner1 extends OuterBInner
}

final class Data[O <: Outer, I <: O#I] private (outer: O, inner: I)

object Data {
  final def apply[O <: Outer, I <: O#I](outer: O, inner: I)(implicit ev: I <:< outer.I): Data[O, I] =
    new Data(outer, inner)
}

val data = new Data(OuterA, OuterA.Inner1) // Does compile.
val data = new Data(OuterA, OuterB.Inner1) // Does not compile.

现在,由于这些示例没有说明如何使用数据类和外部&内部字段,这可能还不够,但希望它对您有所帮助。

如果你有任何疑问,在征求意见时不要犹豫。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57326647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档