Функция фильтра для потокового процессора с ошибкой компиляции входного параметра - PullRequest
2 голосов
/ 27 октября 2019

Я пытаюсь реализовать преобразователь Stream, описанный в разделе «Функциональное программирование в Scala» в главе 15. Авторы не используют дисперсию для параметров типа процесса Process[I, O]. Однако, стремясь по-настоящему понять дисперсию, я добавил дисперсию к параметрам типа как таковым: Process[-I, +O]. Все было хорошо, пока я не попытался реализовать функцию filter и не получил следующую ошибку компиляции:

contravariant type I occurs in covariant position in type I => Boolean of value p

Это код установки, с которым я работал:

 sealed trait Process[-I, +O] { self =>
    import Process._

    def apply(s: Stream[I]): Stream[O] = this match {
      case Halt => Stream()
      case Await(recv) =>
        s match {
          case h #:: t => recv(Some(h))(t)
          case xs      => recv(None)(xs)
        }
      case Emit(h, t) => h #:: t(s)
    }

    def filter(p: I => Boolean): Process[I, O] = self match {
      case Halt => Halt
      case Await(recv) =>
        Await {
          case Some(i) if (p(i)) => recv(Some(i))
          case _                 => recv(None)
        }
      case Emit(head, tail) => Emit(head, tail.filter(p))
    }
  }

  object Process {

    case class Emit[I, O](
        head: O,
        tail: Process[I, O] = Halt
    ) extends Process[I, O]

    case class Await[I, O](
        recv: Option[I] => Process[I, O]
    ) extends Process[I, O]

    case object Halt extends Process[Any, Nothing]
  }

Я уже пытался изменить filter подпись к этому: def filter[II >: I](p: I => Boolean): Process[II, O]

Также попытался изменить Await, чтобы иметь следующие параметры типа:

case class Await[I, O, II >: I](
        recv: Option[I] => Process[II, O]
    ) extends Process[I, O]

Но все жене удалось скомпилировать этот код.

Есть идеи?

1 Ответ

2 голосов
/ 27 октября 2019

Попробуйте

def filter[II <: I](p: II => Boolean): Process[II, O] = ...

с оригиналом Await.

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