scala - Higher kinded type in trait member: _$1 takes no type parameters, expected: 1

173 Views Asked by At

I think there is something I don't quite well understand when I have the following code:

trait Configuration[F[_]] {
  def get(key: String): F[ConfigValue]
}

class InMemoryConfig extends Configuration[Option] {
  override def get(key: String): Option[ConfigValue] = ???
}

class InFileConfig(path: String) extends Configuration[Try] {
  override def get(key: String): Try[ConfigValue] = ???
}

trait Logging {
  def config: Configuration[_] // does not work
  // ...
}

class DefaultLogging {
  override val config = new InMemoryConfig
  // ...
}

The name of the classes are pretty much meaningless, the general goal is to have a member in the trait without defining the param type in order to delay the choice until the implementation (actually in the DefaultLogging class).

1

There are 1 best solutions below

0
Luis Miguel Mejía Suárez On BEST ANSWER

Since Logging doesn't know which type constructor will be used for the Configuration it has to carry over it like any other type parameter.

Thus:

trait Logging[F[_]] {
  def config: Configuration[F]
  // ...
}

The same will apply to whatever depends on Logging it needs to specify the type or keep the dependency.
Thus, a common observation would be if such direct dependency is needed or not, but that becomes a matter of design and sometimes personal preference.