Как я могу получить доступ к членам типа из черты в Scala - PullRequest
2 голосов
/ 14 января 2020

Я пытаюсь создать тип, который отражает идею пары связанных типов.

Затем я хотел бы написать функции, параметризованные для захваченных типов. К сожалению, я не могу правильно express типы и в конечном итоге с несовпадением типов.

У меня есть сильные предпочтения для использования параметров типа и избавления от членов типа, но я не уверен, как еще для ссылки на параметры типа.

Вот мой тестовый код

class Types {

  trait TypePair[A, B] {
    type FROM = A
    type TO   = B
  }

  class Execute[TP <: TypePair[_, _]](func: TP#FROM => TP#TO) {

    def execute(in: TP#FROM): TP#TO = func(in)

  }

}

Вот сообщение об ошибке

Error:(12, 44) type mismatch;
 found   : in.type (with underlying type _$1)
 required: _$1
    def execute(in: TP#FROM): TP#TO = func(in)`

Ответы [ 2 ]

1 голос
/ 14 января 2020

Этого должно быть достаточно для вашего первого требования.

object Types {
  sealed trait Request

  object Request {
    final case object ARequest extends Request
    final case object BRequest extends Request
  }

  sealed trait Response

  object Response {
    final case object AResponse extends Response
    final case object BResponse extends Response
  }

  trait TypePair[I <: Request, O <: Response]

  object TypePair {
    implicit final val ARequestAResponse: TypePair[Request.ARequest, Response.AResponse] =
      new TypePair[Request.ARequest, Response.AResponse]

    implicit final val BRequestAResponse: TypePair[Request.BRequest, Response.AResponse] =
      new TypePair[Request.BRequest, Response.AResponse]

    implicit final val BRequestBResponse: TypePair[Request.BRequest, Response.BResponse] =
      new TypePair[Request.BRequest, Response.BResponse]
  }

  final class Execute[-I, +O](func: I => O)(implicit ev: TypePair[I, O])  {
    def execute(in: I): O = func(in)
  }
}

Я не совсем понимаю ваше второе требование, поэтому я не уверен, достаточно ли этого для того, что вам нужно. Если нет, не стесняйтесь оставлять свой отзыв и редактировать свой вопрос с более подробной информацией. Или откройте новый, если вы чувствуете, что проблема совсем другая.

0 голосов
/ 14 января 2020

Я думаю, что вы можете обойти эту проблему, если избавитесь от подстановочных знаков типа, например:

class Types {

  trait TypePair[A, B] {
    type FROM = A
    type TO = B
  }

  sealed trait ABType
  case class ABTypeInt() extends ABType
  case class ABTypeString() extends ABType

  class Execute[TP <: TypePair[ABType, ABType]](func: TP#FROM => TP#TO) {

    def execute(in: TP#FROM): TP#TO = func(in)
  }

}
...