【问题标题】:Combine related ADTs in a type safe way以类型安全的方式组合相关的 ADT
【发布时间】:2020-09-09 21:21:49
【问题描述】:

我正在设计一个类型安全的 API 来处理“类型”——我正在处理的应用程序中的一个抽象。下面是它的样子:

sealed trait EnumType

case object A extends EnumType
case object B extends EnumType
case object C extends EnumType

sealed abstract class TypeInfo[T <: EnumType](val enumType: T)

case class Ainfo() extends TypeInfo(A)
case class Binfo() extends TypeInfo(B)
case class Cinfo() extends TypeInfo(C)

sealed trait TypeMeta[T <: EnumType]

case class Ameta() extends TypeMeta[A.type]
case class Bmeta() extends TypeMeta[B.type]
case class Cmeta() extends TypeMeta[C.type]

case class TypeDescription[T <: EnumType](info: TypeInfo[T], meta: TypeMeta[T])

我对定义一个接受TypeInfoList 并返回TypeDescription 的函数感到困惑。我目前实现如下:

//Type parameter with omitted bound? Is that type safe?
def toDescription(lst: List[TypeInfo[_]]): List[TypeDescription[_]] = {
  lst map {
    case a: Ainfo => TypeDescription(a, Ameta())
    case b: Binfo => TypeDescription(b, Bmeta())
    case c: Cinfo => TypeDescription(c, Cmeta())
  }
}

为了解决这个问题,我使用了看起来不安全的[_] 模式。有没有办法重新声明函数?

【问题讨论】:

  • 您可以使用 TypeMember 或干脆移除泛型类型。这取决于你想如何使用这些类,但如果你有一个不同类的列表,你似乎不需要泛型。
  • @LuisMiguelMejíaSuárez 引入泛型类型的主要目的是禁止TypeDescription,例如Ainfo()Cmeta()(没有泛型是完全可能的)。
  • 对,没有类型元的类型信息有意义吗?没有类型信息的类型元有意义吗?这些广告还定义了哪些其他操作?
  • @LuisMiguelMejíaSuárez TypeInfoTypeMeta 是两个独立的概念,具有独立的含义。他们的存在是完全明智的。 List[TypeDescription[_]] 旨在发送到前端。

标签: scala type-safety algebraic-data-types


【解决方案1】:

它的类型安全,但是 2 个类型参数单独绑定到它们自己的约束,而不是相互绑定。 如果你想这样做,我认为你需要像这样定义一个方法类型参数

  //Type parameter with omitted bound? Is that type safe?
def toDescription[T<:EnumType](lst: List[TypeInfo[T]]): List[TypeDescription[T]] = {
  lst map {
    case a: Ainfo => TypeDescription(a, Ameta())
    case b: Binfo => TypeDescription(b, Bmeta())
    case c: Cinfo => TypeDescription(c, Cmeta())
  }
}

现在如果你试着写

case a: Ainfo => TypeDescription(a, Bmeta())

你会得到一个编译错误

【讨论】:

  • 这样做的问题是你只能传递同类型信息的List,这对于OP来说可能没什么用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多