Generics 斯卡拉:“我的朋友。”;结构精化中的参数类型不能引用在该精化之外定义的抽象类型;

Generics 斯卡拉:“我的朋友。”;结构精化中的参数类型不能引用在该精化之外定义的抽象类型;,generics,scala,polymorphism,Generics,Scala,Polymorphism,我对scala泛型有问题。虽然我在这里定义的第一个函数似乎很好,但编译器对第二个定义的抱怨如下: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement def >>[B](a: C[B])(implicit m: Monad[C]): C[B] = { ^ 我做错了什么 trait

我对scala泛型有问题。虽然我在这里定义的第一个函数似乎很好,但编译器对第二个定义的抱怨如下:

error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
    def >>[B](a: C[B])(implicit m: Monad[C]): C[B] = {
        ^
我做错了什么

   trait Lifter[C[_]] {
      implicit def liftToMonad[A](c: C[A]) = new {
        def >>=[B](f: A => C[B])(implicit m: Monad[C]): C[B] = { 
          m >>= (c, f)
        }   
        def >>[B](a: C[B])(implicit m: Monad[C]): C[B] = { 
          m >> a
        }   
      }
    }
重要提示:这不是关于单子的问题,而是关于scala多态性的问题

编辑:这是我的单子定义

trait Monad[C[_]] {
  def >>=[A, B](a: C[A], f: A => C[B]): C[B]
  def >>=[B](a: C[B]): C[B]
  def apply[A](a: A): C[A]
}
顺便说一句:我使用的是scala 2.8RC1

问候,,
raichoo

为了填补您示例中的空白,我进行了以下编译:

trait Monad[C[_]] {
  def >>=[A, B](f: A => C[B]): C[B]
  def >>[B](a: C[B]): C[B]
}

trait Lifter[C[_]] {
  class D {
    def >>=[A, B](f: A => C[B])(implicit m: Monad[C]): C[B] = {
      m >>= f
    }
    def >>[B](a: C[B])(implicit m: Monad[C]): C[B] = {
      m >> a
    }
  }

  implicit def liftToMonad[A](c: C[A]) = new D
}

谢谢,这真的很有帮助。你的回答为我指明了正确的方向。我写了这样一封信:

trait Lifter[C[_]] {
  class Wrapper[A](c: C[A])  {
    def >>=[B](f: A => C[B])(implicit m: Monad[C]): C[B] = { 
      m >>= (c, f)
    }   
    def >>[B](b: C[B])(implicit m: Monad[C]): C[B] = { 
      m >> (c, b)
    }   
  }

  implicit def liftToMonad[A](c: C[A]): Wrapper[A] = new Wrapper(c)
}
非常感谢

问候,,
raichoo

如果你在这里有你对
Monad
的定义,那会有帮助。
Monad[C]
部分看起来可疑(我本以为会使用
Monad[C[\u]]
),但如果不知道
Monad
是什么,就很难判断。问题归结为
new{…}
生成了一个匿名结构类型的实例。Scala在如何在结构类型内使用外部的类型参数以促进反射方法调用方面有一些限制。这些限制比必要的要严格一些(为了安全起见)。您可以通过简单地将匿名结构类型替换为命名的本地类型来解决此问题,如答案所示。