Как заставить тип соответствия правильно работать в Scala 3

Мне было очень любопытно посмотреть, смогу ли я перенести свой нетипизированный проект для печати с помощью Scala 3. Вот и я начал:

object Main {
  type HtmlNodeRecord[X]= X match {
    case "tag" => String
    case "attrs" => List[(String, String)]
    case "children" => List[HtmlNode]
  }
  case class HtmlNode(tag: String, attrs: List[(String, String)], children: List[HtmlNode]) {
    def apply(s: "tag" | "attrs" | "children"):  HtmlNodeRecord[s.type] = s match {
      case "tag" => tag
      case "attrs" => attrs
      case "children" => children
    }
  }
}

Не компилируется, выдает ошибку:

> [E007] Type Mismatch Error: Main.scala:10:22
> [error] 10 |      case "tag" => tag
> [error]    |                    ^^^
> [error]    |   Found:    (HtmlNode.this.tag : String)
> [error]    |   Required: Main.HtmlNodeRecord[
> [error]    |     (s : ("tag" : String) | ("attrs" : String) | ("children" : String))
> [error]    |   ]

Я думаю, это происходит из-за того, что он не воспринимает сопоставление с образцом как фильтр типа для s, поскольку считает, что в этом случае s имеет тип "tag" | "attrs" | "children", тогда как случай сопоставления с образцом должен уменьшить его до тега.

Как я могу реализовать запрошенное мной поведение?


person Mikaël Mayer    schedule 19.10.2020    source источник


Ответы (1)


Правильно

type HtmlNodeRecord[X] = X match {
  case "tag" => String
  case "attrs" => List[(String, String)]
  case "children" => List[HtmlNode]
}
case class HtmlNode(tag: String, attrs: List[(String, String)], children: List[HtmlNode]) {
  def apply(s: "tag" | "attrs" | "children"): HtmlNodeRecord[s.type] = s match {
    case _: "tag" => tag
    case _: "attrs" => attrs
    case _: "children" => children
  }
}

https://scastie.scala-lang.org/DmytroMitin/sHIgmxt5wR >

См. Пункт 4 в

  1. У шаблонов выражения соответствия нет охранников
  2. Тип проверяемого выражения соответствия является подтипом типа проверяемого типа соответствия.
  3. Выражение соответствия и тип соответствия имеют одинаковое количество наблюдений.
  4. Шаблоны выражения соответствия являются типизированными шаблонами, и эти типы =:= соответствуют своим шаблонам соответствующих типов в типе соответствия.

http://dotty.epfl.ch/docs/reference/new-types/match-types.html

person Dmytro Mitin    schedule 20.10.2020