简体   繁体   中英

Scala Unable to pimp NaturalTransformation in scalaz or cats

For some reason the following fails to work

object NtExtTest {
  implicit class NaturalTransformExt[M[_], N[_]](val self: NaturalTransformation[M,N]) extends AnyVal {
    def test(b:Boolean) = b
  }
 }

when I call the method test on a natural transform. Intellij recognises it as an extension function, but the compile gives value test is not a member of cats.~> . The same happens when using the scalaz NaturalTransformation. Is there something I can do to help the compile recognise the extension?

Scala version is 2.11.8

An example which fails:

  import NtExtTest._

  class NtTest[B] extends NaturalTransformation[Either[B,?], Xor[B,?]] {
    def apply[A](fa: Either[B, A]): Xor[B, A] = {
      fa match {
        case Left(l) => Xor.left(l)
        case Right(r) => Xor.right(r)
      }
    }
  }

  val test = new NtTest[String]
  test.test(false)

(above uses kind projector plugin, but equally fails with type lambdas, or single param higher kinded types)

Probably relates to SI-8286

object NtExtTest {
  // this will work
  implicit class NatTransExt1[E](val t: NaturalTransformation[Either[E, ?], \/[E, ?]]) {
    def test1(b: Boolean): Boolean = false
  }

  // and this will work
  implicit class NatTransExt2[E](val t: NtTest[E]) {
    def test2(b: Boolean): Boolean = false
  }

  // but this will not work, because NaturalTransformation[F, G] and
  // NaturalTransformation[Either[E, ?], \/[E, ?]] of different kind
  implicit class NatTransExt3[F[_], G[_]](val s: NaturalTransformation[F, G]) {
    def test3(b: Boolean): Boolean = false
  }
}

Ie it is not related to NaturalTransformation . It does not work in simple case as well:

trait SomeType[F[_]]

class SomeConcreteType[A] extends SomeType[Either[A, ?]]

object SomeTypeExt {
  // this will not compile
  implicit class SomeTypeEnrich[F[_]](val t: SomeType[F]) {
    def test1: Boolean = false
  }
  // this will
  implicit class SomeConcreteEnrich[A](val t: SomeType[Either[A, ?]]) {
    def test2: Boolean = true
  }
}

If the goal to extend NtTest , probably NatTransExt1 would be best choice if one would like to stay as generic as possible. NatTransExt2 is ok, if extension really specific to NtTest .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM