scalahigher-kinded-typestype-constructor

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


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).


Solution

  • 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.