首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala3/ Dotty中的依赖元组

Scala3/ Dotty中的依赖元组
EN

Stack Overflow用户
提问于 2020-10-23 04:28:21
回答 1查看 221关注 0票数 3

我正在尝试使用依赖元组列表对依赖映射进行编码。下面是我的一些不起作用的东西:

代码语言:javascript
复制
  class DTuple[Key, ValueMap[_ <: Key]](val first: Key)(val second: ValueMap[first.type])
  
  type DKey = "Tag" | "Versions" | "Author"

  type DMapping[X <: DKey] = X match {
      case "Tag" => String
      case "Versions" => Array[String]
      case "Author" => String
    }
  
  def mkString(d: DTuple[DKey, DMapping]) = d.first match {
    case _: "Tag" => "#" + d.second
    case _: "Versions" => d.second.mkString(",")
    case _: "Author" => "@" + d.second
  }

我得到的只是

代码语言:javascript
复制
[error] -- [E008] Not Found Error: Main.scala:21:35
[error] 21 |    case _: "Versions" => d.second.mkString(",")
[error]    |                          ^^^^^^^^^^^^^^^^^
[error]    |      value mkString is not a member of Main.DMapping[(d.first : Main.DKey)]

我想不出一个好的方法来模式匹配d.second,使它的类型依赖于d.first。我可以添加.asInstanceOf[Array[String]].asInstanceOf[String],但这不是这里的目标,我正在尝试输入校验码。

EN

回答 1

Stack Overflow用户

发布于 2020-10-24 03:11:52

可能有一种更好、更简单的方法可以做到这一点,但是:

代码语言:javascript
复制
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME

// This is a case case solely for the unapply method, you could implement it on your own
case class DTuple[Key, ValueMap[_ <: Key]](first: Key)(val second: ValueMap[first.type])

type DKey = "Tag" | "Versions" | "Author" | "BuildTime"

type DMapping[X <: DKey] = X match {
  case "Tag" => String
  case "Versions" => Array[String]
  case "Author" => String
  case "BuildTime" => ZonedDateTime
}

// the DTuple("<value>") is used at runtime to check the string (DKey) value
// the DTuple["<value>", DMapping] type hint makes dotty see the `d` value as the correct type, hence infering the type of d.second too
def mkString(dt: DTuple[DKey, DMapping]): String = dt match {
  // this would fail at runtime as e.g DTuple("Tag") would enter this case (the `DTuple["BuildTime", DMapping]` is unchecked at runtime
  // case d: DTuple["BuildTime", DMapping] => d.second.format(ISO_ZONED_DATE_TIME)

  // this doesn't compile because `d.second`'s type is still 'DMapping[(d.first : DKey)]', not 'DMapping["BuildTime"]'
  // case d@DTuple("BuildTime") => d.second.format(ISO_ZONED_DATE_TIME)

  case d@DTuple("Tag"): DTuple["Tag", DMapping] => d.second
  case d@DTuple("Versions"): DTuple["Versions", DMapping] => d.second.mkString(", ")
  case d@DTuple("Author"): DTuple["Author", DMapping] => d.second.toString
  case d@DTuple("BuildTime"): DTuple["BuildTime", DMapping] => d.second.format(ISO_ZONED_DATE_TIME)
}

object Main extends App {
  List(
    DTuple[DKey, DMapping]("Versions")(Array("1.0", "2.0")),
    DTuple[DKey, DMapping]("Tag")("env=SO"),
    DTuple[DKey, DMapping]("Author")("MK"),
    DTuple[DKey, DMapping]("BuildTime")(ZonedDateTime.now())
  ).foreach { dt =>
    println(mkString(dt))
  }
}

打印

代码语言:javascript
复制
1.0, 2.0
env=SO
MK
2020-10-23T21:04:06.696+02:00[Europe/Paris]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64490065

复制
相关文章

相似问题

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