Реализовать сопутствующий объект/фабрику в отдельном подмодуле

В моем модуле core sbt есть трейт Matrix для матричного типа данных и трейт MatrixInstance с некоторыми фабричными методами. Предполагается, что сопутствующий объект расширяет эту черту.

В отдельном подмодуле sbt implementation1 хотелось бы это реализовать

object Matrix extends MatrixInstance { ... }

компаньон.

Идея здесь в том, что если я решу иметь вторую реализацию, пользователь библиотеки может просто изменить свой libraryDependencies += ... с implementation1 на implementation2.

Однако, похоже, это не работает. то есть он выглядит как объект, и его компаньон должен находиться в том же модуле (файле?). В противном случае я получаю циклические зависимости, и scalac терпит неудачу.

Есть ли какой-нибудь шаблон, который я могу использовать для достижения этой функциональности? то есть определить черту интерфейса для объекта фабрики/компаньона, реализовать его в отдельном артефакте, а затем разрешить пользователю выбирать между реализациями, только изменив libraryDependencies?


person Luciano    schedule 29.09.2017    source источник


Ответы (1)


Если они должны быть в разных файлах, просто не называйте их Matrix. Вы можете назвать его, например, matrix. Это не будет сопутствующим объектом, поэтому он не будет автоматически включаться в неявный поиск, связанный с Matrix, но при необходимости вы всегда можете импортировать его.

Например, и Scalaz, и Cats имеют объект list, который содержит несколько экземпляров класса типов и синтаксис для stdlib List, например, https://github.com/scalaz/scalaz/blob/v7.2.11/core/src/main/scala/scalaz/std/List.scala

person Ziyang Liu    schedule 29.09.2017
comment
Как вы говорите, это для классов типов, которые предоставляют методы расширения, то есть функциональность, а не сам тип данных. Например, у кошек вы все еще пишете, например. Option(2) для создания типа данных, а не option(2). Здесь я пытаюсь изменить реализацию Option, а не алгебру. - person Luciano; 30.09.2017
comment
Я не думаю, что это то, что вы предлагаете, но может быть возможно создать класс типов, который расширяет исходный объект-компаньон. например implicit class MatrixImpl1(val companion : Matrix.type) { def apply() ...} Не знаю, сработает ли это (например, расширение сопутствующих объектов). - person Luciano; 30.09.2017