有了這個類型的類用於將映射到一個案例類創建一個泛型類的函數被用作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
並不是所有的代碼都提供了,因此測試它並不是很容易,但現在我嘗試了它,那個錯誤。但在我看來,這與問題是正交的。 –