#scala #simulacrum
#scala #симулякр
Вопрос:
У меня есть этот класс типов
import simulacrum._
@typeclass trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B) : F[B]
def lift[A, B](fa: F[A])(f: A => B) : F[A] => F[B] = fa => map(fa)(f)
def as[A, B](fa: F[A], b: => B) : F[B] = map(fa)(_ => b)
def void[A](fa: F[A]) : F[Unit] = as(fa, ())
}
и это реализация
object Functor {
implicit val listFunctor: Functor[List] = new Functor[List] {
def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}
implicit def functionFunctor[X]: Functor[X => ?] = new Functor[X => ?] {
def map[A, B](fa : X => A)(f : A => B) = fa andThen f
}
}
Я могу легко обнаружить неявную реализацию списка как
object Chapter1 extends App {
import Functor.ops._
List(1, 2, 3).as("foo").foreach(println)
}
Вышесказанное работает отлично. Я также могу сделать
object Chapter1 extends App {
import Functor._
val func : Int => String = implicitly[Functor[Int => ?]].map(_ 2)(_.toString)
println(func(5))
}
Но когда я пытаюсь
object Chapter1 extends App {
import Functor.ops._
val x : Int => Int = _ 2
val y : Int => String = x.map(_.toString)
}
Он не находит мою неявную реализацию и говорит, что значение map
не является членом Int => Int
Ответ №1:
Компилятор не может видеть, к Int => Int
чему Int => ?
применяется Int
.
Добавить
scalacOptions = "-Ypartial-unification"
для сборки.sbt.
Это необходимо для нормальной работы с типами более высокого уровня с помощью Cats, Scalaz или вручную.
Кстати, нет смысла import Functor._