Finally tagless

The “finally tagless” style for organising software functionalities is more and more popular. Grafter supports this approach by allowing you to specify a type constructor as the type parameter of a component:

import org.zalando.grafter.macros.{defaultReader, reader}
import cats.Monad

@defaultReader[DatabaseUserOperations]
trait UserOperations[F[_]] {
  def getUser(name: String): F[User]
  def createUser(name: String): F[User]
}

@reader
case class DatabaseUserOperations[F[_]](config: DbConfig)(implicit val m: Monad[F]) extends UserOperations[F] {

  def getUser(name: String): F[User] = ???
  def createUser(name: String): F[User] = ???

}

As you can see there is a minor drawback because you would probably like to write case class DatabaseUserOperations[F[_] : Monad]. This is not currently possible because of this Scala bug. Please vote for it or even better propose a PR on the Scala project!