有了这个类型的类用于将映射到一个案例类创建一个泛型类的函数被用作toCaseClass[User](aUserMap) // returns User
HOWTO使用仿函数
但我也希望能够通过Option [Map []]或Future [Map []]或List [Map []]使用此功能。 所以我实现了用仿函数像这样的通用功能:
def toCaseClass[T <: Product, F[_]: cats.Functor](fOfMaps: F[Map[String, Any]])(implicit mapper: ToCaseClassMapper[T]): F[T] = {
cats.Functor[F].map(fOfMaps)(map => toCaseClass(map)(mapper))
}
但现在这个功能已经被用作toCaseClass[User,List](listOfUserMaps) // returns List[User]
。
不过,我想能够使用的功能
toCaseClass[User](listOfMaps)
toCaseClass[User](futureOfMap)
toCaseClass[User](optionOfMap)
,而无需指定仿函数类型。 这是可能的吗?
可以无形的懒惰来解决这个问题吗?
编辑:解决方案
感谢@ Jasper-m和@ dk14的答案。 所以解决这个问题的'技巧'是在Functor类型之前的类中首先捕获'T'类型。我喜欢@'Jasper-m解决方案与'apply'方法,因为这会保持语法几乎与以前相似。
虽然我做了一些调整。由于已经有'ToCaseClassMapper'类,它也捕获'T'类型,我决定将它与'ToCaseClass'类结合起来。此外,使用@ Jasper-m的方法,当使用'toCaseClass'函数映射某个值时,如Option(value).map(toCaseClass)
,当值为Map或List [Map]时,toCaseClass
的用法必须不同。
我的解决方案如下内容:
@implicitNotFound("Missing ToCaseClassMapper implementation for type ${T}")
trait ToCaseClassMapper[T <: Product] {
def toCaseClass(map: Map[String, Any]): T
import scala.language.higherKinds
def toCaseClass[F[_]: cats.Functor, A](fOfMaps: F[Map[String, A]]): F[T] = {
cats.Functor[F].map(fOfMaps)(toCaseClass)
}
}
由于使用了toCaseClass
功能,其中ToCaseClassMapper
实例已经隐含可用,我决定扔掉功能,只是与mapper.toCaseClass(_)
取代它。这清理了一些不需要的代码,现在使用映射器的语法是相同的,无论该值是Map还是Option,List,Future(或任何其他Functor)。
您使用哪个版本的scala来检查它?我的2.11.8给出:'找不到所有类型cat的证据参数的隐式值。函数[Any]' – dk14
并不是所有的代码都提供了,因此测试它并不是很容易,但现在我尝试了它,那个错误。但在我看来,这与问题是正交的。 –