Найти достойную альтернативу принудительной явной аннотации типа? - PullRequest
0 голосов
/ 12 апреля 2019

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

case class Base[E,S](al:Set[E],sts:Set[MidState[S]],ss:MidState[S],
                            d:Map[(MidState[S],E),MidState[S]],aS:Set[MidState[S]])

case class Edge[E,S](state_1: MidState[S],l:E ,state_2: MidState[S])

sealed trait MidState[S] extends BaseState[S]

sealed case class State[S](l:S)
  extends MidState[S]

case object FailureState extends MidState[Nothing]

База имеет объект-компаньон с методом apply, определенным следующим образом:

object Base {
  def apply [E,S](edges:Set[Edge[E,S]],ss:MidState[S],
  aS:Set[MidState[S]],partialMode:Boolean): Base[E,S]

Когда я пытаюсь создать экземпляр Baseс помощью этого метода применения я не могу обойти явную аннотацию типа для aS:

val aS : Set[MidState[String]] = (State("C") :: Nil).toSet
val base = Base(edges,State("A"),aS,partialMode = true)

Если я удаляю аннотацию явного типа для aS , aS имеет тип Установите [State [S]] , а не Установите [MidState [S]] , который должен быть для метода применения.Есть ли лучшее решение, чтобы избежать этой явной аннотации типа, несмотря на вставку (State ("C") :: Nil) .toSet непосредственно в метод apply?

Ответы [ 2 ]

3 голосов
/ 12 апреля 2019

Первое, что вы можете сделать, это удалить все шумы :: Nil и .toSet и : ...:

val aS = Set[MidState[String]](State("C"))

На самом деле это довольно часто встречается: например, он часто встречается в качестве первого аргумента в fold s, где нужно явно написать Set[Int]() или Set.empty[Int], чтобы получить правильные типы.

Если это все еще слишком шумно, просто добавьте соответствующие фабричные методы к MidState:

object MidState {
  def apply[S](s: S): MidState[S] = State(s)
}

, а затем сразу вызвать фабричный метод, который создает правильный тип объекта:

val bS = Set(MidState("C"))
0 голосов
/ 13 апреля 2019

Андрей Тюкин представил решение, добавив фабричные методы в класс MidState, который отлично работает.Однако я решил проблему, добавив ограничение типа в метод apply, поэтому сигнатура изменилась с:

object Base {
  def apply [E,S](edges:Set[Edge[E,S]],ss:MidState[S],
  aS:Set[MidState[S]],partialMode:Boolean): Base[E,S]

на:

object Base {
  def apply [E,S](edges:Set[Edge[E,S]],ss:MidState[S],
  aS:Set[_ <: MidState[S]],partialMode:Boolean): Base[E,S]

Теперь мы можем передать любой Set aS , который содержит элементы, которые являются подтипами MidState , и это именно то, что я искал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...