Scala Visbility rules question over package scope trait with example taken from cats internal

60 Views Asked by At

In the cats library we have in the package cats.instances

in function.class

trait FunctionInstances extends cats.kernel.instances.FunctionInstances with Function0Instances with Function1Instances

....
....
....

sealed private[instances] trait Function1Instances extends Function1Instances0 {
  implicit def catsStdContravariantMonoidalForFunction1[R: Monoid]: ContravariantMonoidal[* => R] =
    new ContravariantMonoidal[* => R] {
      def unit: Unit => R = Function.const(Monoid[R].empty)
      def contramap[A, B](fa: A => R)(f: B => A): B => R =
        fa.compose(f)
      def product[A, B](fa: A => R, fb: B => R): ((A, B)) => R = {
        case (a, b) => Monoid[R].combine(fa(a), fb(b))
      }
    }

  implicit def catsStdMonadForFunction1[T1]: Monad[T1 => *] =
    new Monad[T1 => *] {
      def pure[R](r: R): T1 => R = _ => r

      def flatMap[R1, R2](fa: T1 => R1)(f: R1 => T1 => R2): T1 => R2 =
        t => f(fa(t))(t)

      override def map[R1, R2](fa: T1 => R1)(f: R1 => R2): T1 => R2 =
        f.compose(fa)

and we can see

sealed private[instances] trait Function1Instances which makes its member only visible in the package Instance

In the Package Object Instances in the package cats, we have:

package object instances {

.......

.......


object function extends FunctionInstances with FunctionInstancesBinCompat0

.......

}

Then in the Invariant.class in cats package, we have:

object Invariant extends ScalaVersionSpecificInvariantInstances with InvariantInstances0 {
....
....

implicit def catsMonadForFunction1[I]: Monad[I => *] = cats.instances.function.catsStdMonadForFunction1[I]

....

I wonder how catsStdMonadForFunction1[I] is visible to Invariant. I thought could only be visble from package instances including the associated package object instances.

So the object function can see and call catsStdMonadForFunction1[I] because it implements the trait and the visibility is scope to package instances . But for I don't understand why Invariant can see that method.

Can someone explain that visbility rule applied here ?

0

There are 0 best solutions below