У меня есть вопрос, очень похожий на этот: Скала дисперсия высшего рода
Это, однако, немного отличается тем, что не компилируется (scala 2.11.8).
Основная идея - взять предоставленный массив «вещей». Если массив равен нулю, вернуть значение по умолчанию некоторого типа (например, Boolean
, Option
, List[Int]
), в противном случае выполнить работу с массивом и получить результат. Результат и значение по умолчанию имеют одинаковый тип.
Проблема, с которой я столкнулся, заключается в том, чтобы заставить ее работать с широким набором типов результатов.
Вот надуманный пример:
trait NullGuard[F[_]] {
def nullGuard[A, B](arr: Array[A], default: F[B])(expr: => F[B]): F[B] =
if (arr == null || arr.length == 0) default else expr
}
Давайте создадим реализацию, которая возвращает Option:
implicit def optionNullGuard[F[X] <: Option[X]]: NullGuard[F] = new NullGuard[F]() {}
Выше скомпилировано, но следующая попытка использовать вышеупомянутый класс типов не делает:
def returnsOption[F[_], A, B](arr: Array[A])(implicit ng: NullGuard[F]): Option[B] = {
ng.nullGuard(arr, None) {
// sample work
if (arr.length % 2 == 0) Option(1) else None
}
}
Я получаю следующую ошибку компиляции:
type mismatch;
found : None.type
required: F[?]
ng.nullGuard(arr, None){
Как мне заставить это работать? Я также открыт для другого подхода, если он есть.