1
votes

Say I have three DSLs I want to use:

sealed trait Test1Op[A]
sealed trait Test2Op[A]
sealed trait Test3Op[A]

object Test1Op {
  case class Test1() extends Test1Op[String]
}

object Test2Op {
  case class Test2() extends Test2Op[String]
}

object Test3Op {
  case class Test3() extends Test3Op[String]
}

the final composition is:

type Api[A] = Coproduct[Test1Op, Coproduct[Test2Op, Test3Op, ?], A]

to make use of it I need appropriate Inject instances (which I believe I should be able to get implicitly as it is with just two DSLs and one coproduct):

  implicit val inj1: Inject[Test1Op, Api] = implicitly
  implicit val inj2: Inject[Test2Op, Api] = implicitly
  implicit val inj3: Inject[Test3Op, Api] = implicitly

this compiles fine. However at runtime they are all null.

// edit:

the problem above seems to be marking these vals as implicit (which causes recursive resolution). After removing implicit it seems to show the correct error, which is:

Error:(28, 36) ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type T def inj1: Inject[Test1Op, Api] = implicitly

and

Error:(28, 36) could not find implicit value for parameter e: T def inj1: Inject[Test1Op, Api] = implicitly

and

Error:(28, 36) type mismatch; found : Unit required: cats.free.Inject[com.example.Test1Op,com.example.Hello.Api] def inj1: Inject[Test1Op, Api] = implicitly

1

1 Answers

1
votes

As usual, found solution just few minutes after asking a question:

  1. Remove implicit (see question edit)
  2. Spit Api[A] type:

    type PartialApi[A] = Coproduct[Test2Op, Test3Op, A]
    type Api[A] = Coproduct[Test1Op, PartialApi, A]
    
  3. Profit from working implicit Inject!