【发布时间】:2017-09-25 13:16:59
【问题描述】:
我正在尝试为 Either 写一个 Functor 用于 Scala 中的学术目的。在higher-kinded 类型和type-projections 的帮助下,我设法为Either 编写了一个实现。
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Functor {
implicit def eitherFunctor[A] = new Functor[({type λ[α] = Either[A, α]})#λ] {
override def map[B, C](fa: Either[A, B])(f: B => C) = fa.map(f)
}
}
def mapAll[F[_], A, B](fa: F[A])(f: A => B)(implicit fe: Functor[F]): F[B] = fe.map(fa)(f)
val right: Either[String, Int] = Right(2)
mapAll(right)(_ + 2)
现在,上面的代码无法编译。我不确定原因,但我得到的编译错误如下 -
Error:(19, 16) type mismatch;
found : Either[String,Int]
required: ?F[?A]
Note that implicit conversions are not applicable because they are ambiguous:
both method ArrowAssoc in object Predef of type [A](self: A)ArrowAssoc[A]
and method Ensuring in object Predef of type [A](self: A)Ensuring[A]
are possible conversion functions from Either[String,Int] to ?F[?A]
mapAll(right)(_ + 2)
有人可以指出我在上面的代码中没有做对吗?
PS:请不要建议我使用kind-projector。
【问题讨论】:
-
Scala 不支持部分应用的类型构造函数。如果一个方法需要一个
F[_],你必须给它一个F[_],而不是一个F[String, _]。 -
@AnshulBajpai 您当前版本的代码在 2.12.3 中编译和运行:
mapAll(right)(_ + 2) //Right(4) -
@DmytroMitin - 我正在使用 scala 2.12.3 我认为它会工作,但它没有。您是否必须打开任何 scala 编译器选项?
-
@AnshulBajpai 是的,你是对的。我的 build.sbt:
scalaVersion := "2.12.3" scalacOptions ++= Seq("-language:higherKinds", "-language:reflectiveCalls", "-Ypartial-unification")。抱歉误导。 -
@DmytroMitin - 仅需要
Ypartial-unification选项才能使编译通过。非常感谢。
标签: scala functor higher-kinded-types type-projection