How does the Scalaz `F [_]: Applicative` constraint imply the use of implicit parameters?

I am trying to understand the following function definition in Traversetrait in Scalaz:

def traverse[F[_] : Applicative, A, B](f: A => F[B], t: T[A]): F[T[B]]

The part that I do not understand is F[_] : Applicative.

Now let's see what Applicative:

trait Applicative[Z[_]] extends Pointed[Z] with Apply[Z] {
  override def fmap[A, B](fa: Z[A], f: A => B): Z[B] = this(pure(f), fa)
  override def apply[A, B](f: Z[A => B], a: Z[A]): Z[B] = liftA2(f, a, (_:A => B)(_: A))
  def liftA2[A, B, C](a: Z[A], b: Z[B], f: (A, B) => C): Z[C] = apply(fmap(a, f.curried), b)
}

Here, to Traversework for some type F, an implicit type object must be added to the scope Applicative[F].

I would like to understand a few things:

  • Wat exactly means F[_] : Applicative?
  • Why F[_]has anything to do with Applicative? We need Applicative[F], and not F [something] extends the applicative law?
  • Why Applicative[F]does this method use implicit type values without declaring implicit parameters?
+5
1

, , :

def traverse[F[_] : Applicative, A, B](f: A => F[B], t: T[A]): F[T[B]]

:

def traverse[F[_], A, B](f: A => F[B], t: T[A])(implicit $ev: Applicative[F]): F[T[B]]

F[_].

+6

All Articles