Проблема уже выявлена. А как насчет решения, которое не требует набора текста?
Решение: неявные преобразования с приоритетом.
Проблема с неявными преобразованиями заключается в том, что вы, вероятно, не хотите писать
неявный def everything_is_optional [A] (a: A) = Некоторые (a)
потому что это нарушает вашу систему типов для вариантов (в том, что вы получите повышение без предварительного уведомления). Может быть, вы хотите этого, но лично мне нравится, когда система типов сообщает мне, когда я запутался в том, является ли что-то опцией или нет. Так что нам нужна какая-то другая обертка. Вот так:
// Might want to do this for more than just one class, so generalize
class Implicator[A,B](val value: A) {
def to[C] = this.asInstanceOf[Implicator[A,C]]
}
class X[A](i: Implicator[Option[A],X[A]]) {
private val v = i.value
def getV = v
}
trait LowPriorityX {
implicit def everything_for_x[A](a: A) = new Implicator(Option(a)).to[X[A]]
}
object X extends LowPriorityX {
implicit def option_for_x[A](oa: Option[A]) = new Implicator(oa).to[X[A]]
}
Теперь мы можем попробовать это (убедитесь, что вы входите в режим :paste
, если вы используете REPL, или вводите все это внутри объекта и импортируете объект, так что object X
интерпретируется как объект-компаньон для class X
:
scala> new X(5)
res0: X[Int] = X@26473f4c
scala> new X(Some(5))
res1: X[Int] = X@1d944379
Таким образом, мы получаем желаемое поведение за счет небольшого количества дополнительного кода и неявного преобразования.
Я почти уверен, что есть схема кодирования типов, которая также будет работать, но у меня не было времени ее закончить, плюс я потерял энтузиазм, как только заметил, что компилятор настаивает на создании и упаковке неявного используемого для ограничения типов в таких схемах, хотя это необходимо только для проверки типов.