Scala 不成形的。修改标记类型

Scala 不成形的。修改标记类型,scala,shapeless,phantom-types,Scala,Shapeless,Phantom Types,例如,我有两种标记类型: trait Created type CreatedDttm = LocalDateTime @@ Created type CreatedTs = Timestamp @@ Created 这些类型用于处理模型。第一个用于通用模型,第二个用于db实体 final case class Entity(created: CreatedDttm) // Common model final case class EntityRow(created: CreatedTs

例如,我有两种标记类型:

trait Created
type CreatedDttm = LocalDateTime @@ Created
type CreatedTs = Timestamp @@ Created
这些类型用于处理模型。第一个用于通用模型,第二个用于
db
实体

final case class Entity(created: CreatedDttm)   // Common model
final case class EntityRow(created: CreatedTs)  // DB model
我的资料来源中有一个转换器:

def toModel(e: EntityRow) = Entity(e.created.toLocalDateTime)   // Does not compile
此转换不会编译,因为
e.created.toLocalDateTime
返回
LocalDateTime
,但
实体
需要
LocalDateTime
创建的
标记

因此,我必须将转换更改为
tag[Created](e.Created.toLocalDateTime)
,才能编译此代码。这很管用,但是,天哪,它看起来有点难看

Timestamp
由创建的
标记,新的
LocalDateTime
也必须由创建的
标记


是否有任何方法可以在不需要重新标记新修改值的情况下修改标记的类型?

恐怕没有。我认为你能做到最好,尽量减少你的痛苦。我将使用一个隐式类和一个类似
的方法来创建DDTTM
。大概是这样的:

implicit class LocalDateTimeOps(value: LocalDateTime) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value)
}
implicit class TimestampOps(value: Timestamp) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value.toLocalDateTime)
}
然后您可以将线路更改为:

def toModel(e: EntityRow) = Entity(e.created.toLocalDateTime.toCreatedDttm)
或者,您可以让隐式类直接在
时间戳上操作,如下所示:

implicit class LocalDateTimeOps(value: LocalDateTime) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value)
}
implicit class TimestampOps(value: Timestamp) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value.toLocalDateTime)
}
那么这条线可以是:

def toModel(e: EntityRow) = Entity(e.created.toCreatedDttm)

恐怕不行。我认为你能做到最好,尽量减少你的痛苦。我将使用一个隐式类和一个类似
的方法来创建DDTTM
。大概是这样的:

implicit class LocalDateTimeOps(value: LocalDateTime) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value)
}
implicit class TimestampOps(value: Timestamp) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value.toLocalDateTime)
}
然后您可以将线路更改为:

def toModel(e: EntityRow) = Entity(e.created.toLocalDateTime.toCreatedDttm)
或者,您可以让隐式类直接在
时间戳上操作,如下所示:

implicit class LocalDateTimeOps(value: LocalDateTime) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value)
}
implicit class TimestampOps(value: Timestamp) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value.toLocalDateTime)
}
那么这条线可以是:

def toModel(e: EntityRow) = Entity(e.created.toCreatedDttm)

标准方法是重新标记。你们可以施法,但标记实际上是施法。标准的方法是重新标记。你可以施法,但标记实际上是施法。