Call a common function using Functor using a subclass (cats / scalaz)

I fiddled with some basic Cats / Scalaz examples, and also go through tutorials to get a feel for it, and I hit the case, and I'm sure there is a solution.

Is it possible to call a generic function that takes a contextualized value ( F[A]) with a Functor ( F[_] : Functor) representation with a context <: F? I know that Functor is type-invariant F[_], and I also know about existence Functor.widen, but it seems strange that there is no way to implicitly extend my type for use in a common function.

Example in Cats (a similar example with Scalaz also exists):

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, calling the Functor for Parameter function is explicit and the display works as expected

Functor[Option].map(Some(1))(_ + 1) // Some(2)

, : , - " ", , Scala stdlib?

+4
2

, Dmytro . , cat/scalaz .some, Option, Some Some;

takesAFunctor(1.some)

Apply; takesAFunctor(1.pure[Option])

- " ", , Scala stdlib?

, Option , - . Option, Some - , Functor[Option].map Option Option, .

, , , , java-ish haskell-ish

+1
// No implicit for Functor[Some]. 
// Makes sense, but can we summon one since we have a Functor[Option]?

?

  implicit def subtypeFunctor[F[_], G[T] <: F[T]](implicit functor: Functor[F]): Functor[G] = new Functor[G] {
    override def map[A, B](ga: G[A])(f: A => B): G[B] = functor.map(ga)(f)
  }

, functor.map(ga)(f) F[B] G[B].

, , , .

Functor F T F[T] f: A => B map(f): F[A] => F[B] ( ). F F[B] F F[A] , .

, takesAFunctor takesAFunctor[Option](Some(1)).

+1

Source: https://habr.com/ru/post/1688939/


All Articles