Reputation: 139
I have a have an implicit class like this
private[this] implicit class OptionListUtil[A, B <: List[A]](option: Option[B]) {
def defaultMap[C](f: A => C): Seq[C] = option.getOrElse(Seq.empty[A]).map(f)
But when I go ahead and call it on a Option[List[A]], I get the value defaultMap is not a member of Option[List[A]]
Intellij is not giving any hints so I'm pretty lost
Upvotes: 1
Views: 300
Reputation: 170859
Generally, if a type parameter only appears once it's suspicious. In this case B
is actually useless and you can simplify OptionListUtil
to
private[this] implicit class OptionListUtil[A](option: Option[List[A]]) {
def defaultMap[C](f: A => C): Seq[C] = option.getOrElse(Seq.empty[A]).map(f)
}
because Option
is covariant. This is much simpler for type inference to handle.
Upvotes: 4
Reputation: 139
Looks like another way to address this is with higher kinded generics with the class signature like:
private[this] implicit class OptionListUtil[A, B[A] <: List[A]](option: Option[B[A]])
Upvotes: 0
Reputation: 1241
Go with this instead:
implicit class OptionListUtil[A,B](option: Option[B])(implicit ev: B <:< List[A]) {
def defaultMap[C](f: A => C): Seq[C] = option.toSeq.flatMap(_.map(f))
}
The current scala compiler can't infer the type A
in your B <: List[A]
quite right yet. Asking for the implicit evidence of <:<
in these cases helps the compiler with type inference.I read somewher that the new dotty compiler apparently doesn't have this issue.
Upvotes: 0