Лучший способ достичь желаемого - использовать класс типа Functor .Например, вот пример использования Кошки .
(Вы можете сделать то же самое, используя Scalaz ) .
import scala.language.higherKinds
import cats.Functor
import cats.syntax.functor.toFunctorOps
final case class Test[A, C[_]](init: A, trans: Map[A,C[A]])(implicit CFunctor: Functor[C]) {
def convert[B](conv: A => B): Test[B, C] = {
val _init = conv(init)
val _trans = trans map { case (k,v) => conv(k) -> v.map(x => conv(x)) }
Test(_init, _trans)
}
}
Однако, если по какой-то причине вы не можете или не хотите использовать Cats / Scalaz, вы можете попробовать Структурные типы .
import scala.language.higherKinds
import scala.language.reflectiveCalls
final case class Test[A, C[A] <: { def map[B](f: A => B): C[B]}](init: A, trans: Map[A,C[A]]){
def convert[B](conv: A => B): Test[B, C] = {
val _init = conv(init)
val _trans = trans map { case (k,v) => conv(k) -> v.map(x => conv(x)) }
Test(_init, _trans)
}
}
Тем не менее, обратите вниманиечто последний будет работать для Option
, но не будет работать для List
, просто потому, что метод map
в List получает неявный CanBuildFrom
, и по этой причине он не равен желаемому.