【问题标题】:Scala Unable to pimp NaturalTransformation in scalaz or catsScala 无法在 scala 或猫中进行自然转换
【发布时间】:2016-04-18 17:14:19
【问题描述】:

由于某种原因,以下无法正常工作

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

当我在自然变换上调用方法 test 时。 Intellij 将其识别为扩展函数,但编译给出 value test is not a member of cats.~> 。使用 scalaz NaturalTransformation 时也会发生同样的情况。我可以做些什么来帮助编译器识别扩展名吗?

Scala 版本是 2.11.8

一个失败的例子:

  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)

(上面使用了种类投影仪插件,但对于 lambdas 类型或单参数更高种类的类型同样失败)

【问题讨论】:

  • 产生该错误的实际代码是什么?
  • 隐式类应该在另一个对象/特征/类中。尝试将您的NaturalTransformExt 类包装在一个对象中(例如Foo)并在调用import Foo._ 之前说test.test(false) docs.scala-lang.org/overviews/core/implicit-classes.html
  • @smoes 抱歉只是假设给定的,相应地更改了代码
  • 那么,产生了什么错误?
  • 值测试不是NtTest的成员

标签: scala scalaz scala-cats kind-projector


【解决方案1】:

可能与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
  }
}

即它与NaturalTransformation 无关。它也不适用于简单的情况:

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
  }
}

如果目标是扩展NtTest,如果希望尽可能保持通用性,NatTransExt1 可能是最佳选择。 NatTransExt2 没问题,如果扩展名确实特定于 NtTest

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2011-02-28
    • 2019-10-09
    相关资源
    最近更新 更多