У меня проблема с дженериками 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
С уважением, Райчу
Monad
здесь. ЧастьMonad[C]
выглядит подозрительно (я бы подумал, что будет использоватьсяMonad[C[_]]
), но трудно сказать, не зная, что такоеMonad
. - person Rex Kerr   schedule 21.04.2010new { … }
создает экземпляр анонимного структурного типа. Scala имеет некоторые ограничения на то, как параметры типа извне могут использоваться внутри структурных типов, чтобы облегчить вызовы рефлексивных методов. Эти ограничения несколько строже, чем необходимо (чтобы ошибиться на всякий случай). Вы можете обойти эту проблему, просто заменив анонимный структурный тип именованным локальным типом, как показано в ответе. - person Vladimir Reshetnikov   schedule 01.12.2017