I've been messing around with some basic examples of Cats/Scalaz and also walking through tutorials to get a feel and I've hit a case which I'm sure there is a solution to.
Is it possible to call a generalized function that takes a contextualized value (F[A]
) with a Functor view (F[_] : Functor
) with a context that is <: F
? I'm aware that Functor is invariant on type F[_]
, and I'm also aware of the existence of Functor.widen
, but it seems strange that there is no way to implicitly widen my type for use in a general function.
An example in Cats (a similar example with Scalaz exists as well):
import cats.instances.all._
import cats.syntax.all._
def takesAFunctor[F[_] : cats.Functor](f: F[Int]) = f.map(_ + 1)
takesAFunctor(Option(1)) // Works fine (of course)
takesAFunctor(Some(1)) // No implicit for Functor[Some]. Makes sense, but can we summon one since we have a Functor[Option]?
takesAFunctor(Some(1): Option[Int]) // Works but very verbose
Of course, summoning the Functor for Option explicitly and mapping works as expected
Functor[Option].map(Some(1))(_ + 1) // Some(2)
So my question is: Does the signature of the general function need to change to account for the subclassed context, is there some sort of "implicit widening" that I don't know about, or is this just an unfortunate drawback to functional programming in Scala using the stdlib?