Scala中的复和类型

Posted

技术标签:

【中文标题】Scala中的复和类型【英文标题】:Complex Sum Type in Scala 【发布时间】:2021-03-23 07:02:37 【问题描述】:

我有以下需要建模的类型:

sealed trait FieldType

case object INT extends FieldType
case object UINT extends FieldType
case object FLOAT extends FieldType
case object DOUBLE extends FieldType
case object BOOL extends FieldType
case object STRING extends FieldType
case object DATETIME extends FieldType

case class LIST(fieldType: FieldType) extends FieldType
case class SET(fieldType: FieldType)  extends FieldType

我遇到的问题是实际上LISTSET 实际上是包含FieldType 的ComplexFieldType换句话说,LIST 不能包含 List 或 SET,SET 也是如此。

什么是建模的正确方法,以确保穷举性问题,即让编译器告诉我何时我缺少一些值。

我尝试像 SimpleFieldTypeComplexFieldType 那样引入中间密封特征,但后来模式匹配搞砸了。

我看到的唯一解决方案是我不想像中那样复合

case object LIST_INT

是为LISTSET使用智能构造函数。

不过,我想写个便条,看看 scalaSphere 知道些什么。

【问题讨论】:

中间特征是合适的解决方案,你不需要匹配中间特征只匹配最终值。 为什么不用Scala提供的TypeTag? @texasbruce 这增加了对scala-reflect的依赖,运行时反射比较慢,而且2.x中有bugs的反射,目前还没有积极修复。 【参考方案1】:

确实如此:

sealed trait FieldType

sealed trait SimpleFieldType extends FieldType
case object INT extends SimpleFieldType
case object UINT extends SimpleFieldType
case object FLOAT extends SimpleFieldType
case object DOUBLE extends SimpleFieldType
case object BOOL extends SimpleFieldType
case object STRING extends SimpleFieldType
case object DATETIME extends SimpleFieldType
sealed trait ComplexFieldType extends FieldType
case class LIST(fieldType: SimpleFieldType) extends ComplexFieldType
case class SET(fieldType: SimpleFieldType)  extends ComplexFieldType
val field1: FieldType = INT

field1 match 
    case FLOAT =>
    case BOOL =>
    case INT =>
    case UINT =>
    case DATETIME =>
    case DOUBLE =>
    case STRING =>
    case LIST(_) =>
    case SET(_) =>


ScalaC 检测非穷举性。我只需要使用https://github.com/rtimush/sbt-rewarn#sbt-rewarn 作为重新编译就跳过它

【讨论】:

以上是关于Scala中的复和类型的主要内容,如果未能解决你的问题,请参考以下文章

Scala 中的高级类型是啥?

Scala中的通用递归类型

点击两次以突出显示收藏视图中的复选标记

表单中的 SwiftUI Picker 不显示来自 CoreData 的复选标记

Haskell 在 Scala 中的新类型

Scala中的变量类型和操作