Допустим, у нас есть класс, который имеет ковариантный и контра- параметр типа:Как определить flatMap для класса с параметрами ковариантного/контравариантного типа?
sealed trait Pipe[-I,+O,+R]
// case subclasses
И мы имеем монадических операции, определенные для экземпляров этого класса:
object Pipe {
def flatMap[I,O,Ri,R](p: Pipe[I,O,Ri], f: Ri => Pipe[I,O,R]): Pipe[I,O,R] =
...
}
Чтобы иметь возможность использовать for
-comprehension, нам нужно, чтобы flatMap
является метод самого признака:
sealed trait Pipe[-I,+O,+R] {
def flatMap[I,O,Ri,R](f: Ri => Pipe[I,O,R]): Pipe[I,O,R] =
Pipe.flatMap(this, f);
}
Однако это делает п OT компиляции, он терпит неудачу с
контравариантного типа
I
происходит в ковариантной позиции в типе(R) => Pipe[I,O,R1]
значенияf
.
(Подобная ошибка возникает для параметров ковариант- типа, а также.)
Я понимаю, ограничение и поэтому возникает проблема. Но есть ли способ обхода, как определить flatMap
по признаку, используя Pipes.flatMap
с той же семантикой, что и выше? Возможно, используя некоторые неявные преобразования и/или промежуточный класс строителя?