免费monad - 隐式Inject与嵌套Coproduct使用猫

时间:2016-10-27 13:42:23

标签: scala scala-cats

假设我有三个想要使用的DSL:

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]
}
最后的作文是:

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

要使用它我需要适当的Inject实例(我相信我应该可以隐含地使用它,因为只有两个DSL和一个副产品):

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

这编译好了。但是在运行时它们都是null

//编辑:

上面的问题似乎是将这些值标记为implicit(导致递归解析)。删除implicit后,它似乎显示正确的错误,即:

错误:(28,36)含糊不清的隐含值:  两个值StringCanBuildFrom在对象Predef中的类型=> scala.collection.generic.CanBuildFrom [字符串,字符,字符串]  和方法$符合对象Predef的类型[A] => <:其中[A,A]  匹配预期类型T.   def inj1:注入[Test1Op,Api] =隐式

错误:(28,36)找不到参数e:T的隐含值   def inj1:注入[Test1Op,Api] =隐式

错误:(28,36)类型不匹配;  发现:单位  必需:cats.free.Inject [com.example.Test1Op,com.example.Hello.Api]   def inj1:注入[Test1Op,Api] =隐式

1 个答案:

答案 0 :(得分:1)

像往常一样,在提问后几分钟找到解决方案:

  1. 删除implicit(请参阅问题编辑)
  2. 吐出Api[A]类型:

    type PartialApi[A] = Coproduct[Test2Op, Test3Op, A]
    type Api[A] = Coproduct[Test1Op, PartialApi, A]
    
  3. 隐含Inject工作的利润!