ОБНОВЛЕНИЕ:
Я думаю, чтобы это работало, вам нужно включить некоторые дополнительные опции для компилятора в build.sbt
:
scalacOptions ++= Seq(
"-Ypartial-unification",
"-language:postfixOps",
"-language:higherKinds",
"-deprecation",
"-encoding", "UTF-8",
"-feature",
"-unchecked"
)
Подробнее офлаг частичное объединение и то, что он решает , можно найти здесь .
ОРИГИНАЛЬНЫЙ ОТВЕТ : Вы выполняете свой код через Worksheet или Scratchв идее?Я заметил, что иногда, особенно в такого рода задачах функционального программирования, где есть вывод типа, неявное разрешение и «магический» тип с более высоким родом, REPL IDEA не соответствуют задаче (но я не уверен почему).
При этом я пытался запустить на IDEA следующее:
object TestApp extends App{
trait Functor[F[_]] {
def fmap[A, B](fa: F[A])(f: A => B): F[B]
}
implicit class FunctorOps[F[_]: Functor, A](self: F[A]) {
def fmap[B](f: A => B): F[B] = implicitly[Functor[F]].fmap(self)(f)
}
case class Reader[A, B](run: A => B)
type ReaderF[X] = ({ type L[A] = Reader[X, A] })
implicit def readerFunctors[E]: Functor[ReaderF[E]#L] =
new Functor[ReaderF[E]#L] {
override def fmap[A, B](fa: Reader[E, A])(f: A => B): Reader[E, B] =
Reader(e => f(fa.run(e)))
}
val foo: Reader[String, Int] = Reader[String, Int](s => s.length)
val i = foo.fmap(_ + 1)
println(i.run("Test"))
println(i.run("Hello World"))
}
И все работает нормально, печатая 5
и 12
.Кроме того, как кто-то еще упомянул, ваш код работает на Scastie, который является еще одним синтезом IDEA.
Последнее замечание: вы, вероятно, уже знаете это, но вы можете избежать всего этого уродства лямбда-типов, используя плагин компилятора kind-проектора .
Короче говоря, отбросьте псевдоним типа ReaderF[X]
и сделайте свой экземпляр функтора похожим на:
implicit def readerFunctors[X]: Functor[Reader[X,?]] =
new Functor[Reader[X,?]] {
override def fmap[B, C](fa: Reader[X,B])(f: B => C): Reader[X,C] =
Reader(e => f(fa.run(e)))
}
более читабельное ИМХО.