复合材料的Scala类型类
我有一个和类型,映射:复合材料的Scala类型类,scala,typeclass,scala-cats,Scala,Typeclass,Scala Cats,我有一个和类型,映射: sealed trait Mapping final case class XMapping(a:String) final case class FallbackMapping(mappings: List[Mapping]) 我有一个typeclass,定义如下: final case class Param(x:String) trait ParameterLoader[T] { def load(mapping:T) : List[Param] } 在某
sealed trait Mapping
final case class XMapping(a:String)
final case class FallbackMapping(mappings: List[Mapping])
我有一个typeclass,定义如下:
final case class Param(x:String)
trait ParameterLoader[T] {
def load(mapping:T) : List[Param]
}
在某些情况下:
object DefaultParameterLoaders {
implicit val xParameterLoader= new QueryParameterLoader[XMapping] {
override def load(mapping: XMapping): List[Param] = List(Param(mapping.a))
}
implicit val fallbackParameterLoader = new ParameterLoader[FallbackMapping] {
override def load(mapping: FallbackMapping): List[Param] =
mapping.mappings.flatMap(x => ???)
}
}
我找不到将隐式实例传递到上面的flatMap的方法。我得到的错误是缺少ParameterLoader[Mapping]的一个实例。有没有办法告诉编译器应该使用范围内的任何类型类实例 类型系统正在寻找一个
ParameterLoader[Mapping]
,这意味着ParameterLoader[XMapping]
/ParameterLoader[FallbackMapping]
不够具体。您需要提供一个参数加载器[映射]
。可以使用现有的定义执行此操作
implicit def mappingLoader(implicit xpLoader: ParameterLoader[XMapping], fmLoader: ParameterLoader[FallbackMapping]) = new ParameterLoader[Mapping] {
def load(mapping: Mapping): List[QueryParam] =
mapping match {
case xm: XMapping = xpLoader.load(xm)
case fm: FallbackMapping => fmLoader.load(fm)
}
}
或者,让flatmap执行匹配逻辑:
implicit def fallbackParameterLoader(implicit xpLoader: ParameterLoader[XMapping]) = new ParameterLoader[FallbackMapping] {
override def load(mapping: FallbackMapping): List[Param] =
mapping.mappings.flatMap {
case xm: XMapping = xpLoader.load(xm)
case fm: FallbackMapping => this.load(fm)
}
}
谢谢这很有效。我希望能以某种方式实现自动化。这将锁定所使用的实例,而理想情况下,我希望使用客户机范围内的任何实例。可能吗?是的。不要像我所做的那样显式地指定参数加载器,而是隐式地使用
ParameterLoader[XMapping].load(xm)
代替xParameterLoader.load(xm)
。但是,这将使用在构建参数加载器时在范围内的参数加载器。我已经更新了我的答案以支持您的用例。这将基于范围内的任何参数加载程序派生mappingLoader。请记住,有这样的派生,行为可能会令人困惑,因为导入可以改变行为。确保这是一个很好的文档,让你的团队知道它是如何工作的。如果你有任何其他问题,请随时提问。