0

In my core sbt module, I have an trait Matrix for a matrix data type, and a trait MatrixInstance that has some factory methods. The companion object is supposed to extend this trait.

In a separate sbt submodule implementation1, I would like to implement this

object Matrix extends MatrixInstance { ... }

companion.

The idea here is that if I decide to have a second implementation, the library user could just change his libraryDependencies += ... from implementation1 to implementation2.

However, this doesn't seem to work. i.e. it looks like an object and it's companion must reside in the same module (file?). Otherwise I get circular dependencies and scalac fails.

Is there any pattern I can use to achieve this functionality? i.e. define the interface trait for the factory/companion object, have it implemented in a separate artifact, and then allow the user to choose between the implementations by only changing libraryDependencies?

Luciano
  • 2,388
  • 1
  • 22
  • 33

1 Answers1

0

If they must be in different files, just don't call it Matrix. You can name it, for example, matrix. It won't be a companion object, so it will not be included automatically in implicit search related to Matrix, but you can always import it if necessary.

As an example, both Scalaz and Cats have a list object that contains a number of type class instances and syntaxes for the stdlib List, e.g., https://github.com/scalaz/scalaz/blob/v7.2.11/core/src/main/scala/scalaz/std/List.scala

Ziyang Liu
  • 810
  • 4
  • 10
  • Like you say, this is for type-classes that provide extension methods, i.e. functionality, rather than the data type itself. In cats for example you still write e.g. `Option(2)` to create the data type, not `option(2)`. What I'm trying to change here is the implementation of `Option` rather than it's algebra. – Luciano Sep 30 '17 at 12:10
  • I don't think this is what you're suggesting, but it may be possible to create a typeclass that extends the original companion object. e.g. `implicit class MatrixImpl1(val companion : Matrix.type) { def apply() ...}` Dunno if that will work though (i.e. extending companion objects). – Luciano Sep 30 '17 at 12:31