Scala: проблема вывода типа - PullRequest
       75

Scala: проблема вывода типа

0 голосов
/ 20 сентября 2018

У меня есть:

sealed trait Par[A]{def foo = ???}
case class Unit[A](v: () => A) extends Par[A]
case class Map2[L, R, A](parLeft: Par[L],
                         parRight: Par[R],
                         map: (L, R) => A) extends Par[A]

Моя проблема в том, что когда я сопоставляю паттерн с p:Par[A], я делаю что-то вроде этого:

def getSequentially: A = this match {
  case Par.Unit(f) => f()
  case Par.Map2(a, b, f) => f(a.getSequentially, b.getSequentially)
}    

L и Rв инспекторе типов Intellij предполагается значение Any, а вызовы getSequentially выделены красным, предупреждение: type mismatch, expected Nothing, actual Any, поскольку ожидается, что f будет иметь тип: (Nothing, Nothing) => A.Хотя он на самом деле работает и компилируется.

Мне кажется, я понимаю, в чем проблема, и я должен быть в состоянии решить ее с помощью экзистенциальных типов в определении Map2.Единственная проблема в том, что параметр map имеет зависимый тип, поэтому я не знаю, как это сделать.Может быть, я должен сделать вариант шаблона AUX?

Мой вопрос, во-первых, почему он компилируется, а во-вторых, если есть способ реструктурировать зависимость типа, чтобы он больше не выдавал предупреждение.

1 Ответ

0 голосов
/ 20 сентября 2018

Если вы хотите иметь экзистенциалы, вы можете использовать печатные шаблоны:

sealed trait Par[A]{
  def getSequentially: A = this match {
    case x: Par.Unit[A] => x.v()
    case x: Par.Map2[_, _, A] => x.map(x.parLeft.getSequentially, x.parRight.getSequentially)
  }
}

object Par {
  case class Unit[A](v: () => A) extends Par[A]
  case class Map2[L, R, A](parLeft: Par[L],
                           parRight: Par[R],
                           map: (L, R) => A) extends Par[A]
}

Кажется, IntelliJ не выделяет это.

...