В последнее время у Scala блоггеров много энтузиазма для шаблонов типов, в которых простой класс имеет функциональность, добавленную к нему дополнительным классом, соответствующим некоторому признаку или шаблону, В качестве упрощенного примера простой класс:
case class Wotsit (value: Int)
может быть адаптирован к признаку Foo:
trait Foo[T] {
def write (t: T): Unit
}
с помощью этого типа:
implicit object WotsitIsFoo extends Foo[Wotsit] {
def write (wotsit: Wotsit) = println(wotsit.value)
}
Тип типа обычно фиксируется во время компиляции с помощью implictions, позволяя вместе с Wotsit и его классом классов выполнять функцию более высокого порядка:
def writeAll[T] (items: List[T])(implicit tc: Foo[T]) =
items.foreach(w => tc.write(w))
writeAll(wotsits)
(прежде чем вы меня исправите, я сказал, что это упрощенный пример)
Однако, использование implicits предполагает, что точный тип элементов известен во время компиляции. Я нахожу в своем коде, что часто это не так: у меня будет список некоторых типов элементов List [T], и вам нужно будет найти правильный класс типа для работы над ними.
Предлагаемый подход Scala должен был бы добавить аргумент typeclass во всех точках иерархии вызовов. Это может вызвать раздражение в виде шкал кода, и эти зависимости нужно передавать более длинные цепи, используя методы, к которым они становятся все более неуместными. Это делает код загроможденным и сложнее поддерживать, что противоположно тому, что означает Scala.
Как правило, это то, где будет введена инъекция зависимостей, используя библиотеку для доставки желаемого объекта в нужную ему точку. Детали меняются в зависимости от библиотеки, выбранной для DI - в прошлом я написал свое собственное Java, но, как правило, точка инъекции должна точно определять желаемый объект.
Проблема в том, что в случае класса типа точное значение неизвестно во время компиляции. Он должен быть выбран на основе полиморфного описания. И что важно, информация о типе была удалена компилятором. Манифесты - это Scala решение для стирания типа, но мне не ясно, как использовать их для решения этой проблемы.
Какие методы и библиотеки вложений для инъекций для Scala могли бы предложить люди как способ решения этой проблемы? Мне не хватает трюка? Идеальная библиотека DI? Или это действительно точка прилипания, которая кажется?
Разъяснение
Я думаю, что на самом деле есть два аспекта. В первом случае точка, в которой требуется класс типа, достигается прямыми вызовами функций из точки, где известен точный тип ее операнда, и поэтому достаточный тип перебора и синтаксического сахара может позволить классу классов быть переданным в укажите, что это необходимо.
Во втором случае две точки разделены барьером - таким как API, который нельзя изменить или хранить в базе данных или хранилище объектов, или сериализовать и отправить на другой компьютер - это означает тип класс не может быть передан вместе с его операндом. В этом случае, учитывая объект, тип и значение которого известны только во время выполнения, тип класса должен каким-то образом быть обнаружен.
Я думаю, что у функциональных программистов есть привычка принимать первый случай - что с достаточно продвинутым языком тип операнда всегда будет познаваемым. Давид и mkniessl дали хорошие ответы на это, и я, конечно, не хочу критиковать их. Но второй случай определенно существует, и именно поэтому я ввел вопрос об ответственности в вопрос.