Scala:类型推断和子类型/更高种类的类型
我一直在玩 Scalaz,以便在 scala 中获得一点 Haskell 的感觉。到 了解 scala 中的工作原理 我开始自己实现各种代数结构,并遇到了 Scalaz 人员提到的一种行为。
这是我实现函子的示例代码:
trait Functor[M[_]] {
def fmap[A, B](a: M[A], b: A => B): M[B]
}
sealed abstract class Foo[+A]
case class Bar[A]() extends Foo[A]
case class Baz[A]() extends Foo[A]
object Functor {
implicit val optionFunctor: Functor[Option] = new Functor[Option]{
def fmap[A, B](a: Option[A], b: A => B): Option[B] = a match {
case Some(x) => Some(b(x))
case None => None
}
}
implicit val fooFunctor: Functor[Foo] = new Functor[Foo] {
def fmap[A, B](a: Foo[A], b: A => B): Foo[B] = a match {
case Bar() => Bar()
case Baz() => Baz()
}
}
}
object Main {
import Functor._
def some[A](a: A): Option[A] = Some(a)
def none[A]: Option[A] = None
def fmap[M[_], A, B](a: M[A])(b: A => B)(implicit f: Functor[M]): M[B] =
f.fmap(a, b)
def main(args: Array[String]): Unit = {
println(fmap (some(1))(_ + 1))
println(fmap (none)((_: Int) + 1))
println(fmap (Bar(): Foo[Int])((_: Int) + 1))
}
}
我为 Option 编写了一个函子实例和一个虚假的 sumtype Foo。问题在于,如果没有显式类型注释或包装器方法,Scala 无法推断出隐式参数。
def some[A](a: A): Option[A] = Some(a)
println(fmap (Bar(): Foo[Int])((_: Int) + 1))
如果没有这些解决方法,Scala 就会推断出 Functor[Bar] 和 Functor[Some] 等类型。
这是为什么?谁能指出我的语言规范中定义此行为的部分吗?
问候, 雷鸟
I've been playing around with Scalaz to get a little bit of the haskell feeling into scala. To
understand how things work in scala I started implementing various algebraic structures myself and came across a behavior that has been mentioned by the Scalaz folks.
Here is my example code which implements a functor:
trait Functor[M[_]] {
def fmap[A, B](a: M[A], b: A => B): M[B]
}
sealed abstract class Foo[+A]
case class Bar[A]() extends Foo[A]
case class Baz[A]() extends Foo[A]
object Functor {
implicit val optionFunctor: Functor[Option] = new Functor[Option]{
def fmap[A, B](a: Option[A], b: A => B): Option[B] = a match {
case Some(x) => Some(b(x))
case None => None
}
}
implicit val fooFunctor: Functor[Foo] = new Functor[Foo] {
def fmap[A, B](a: Foo[A], b: A => B): Foo[B] = a match {
case Bar() => Bar()
case Baz() => Baz()
}
}
}
object Main {
import Functor._
def some[A](a: A): Option[A] = Some(a)
def none[A]: Option[A] = None
def fmap[M[_], A, B](a: M[A])(b: A => B)(implicit f: Functor[M]): M[B] =
f.fmap(a, b)
def main(args: Array[String]): Unit = {
println(fmap (some(1))(_ + 1))
println(fmap (none)((_: Int) + 1))
println(fmap (Bar(): Foo[Int])((_: Int) + 1))
}
}
I wrote a functor instance for Option and a bogus sumtype Foo. The problem is that scala cannot infer the implicit parameter without an explicit type annotation or a wrapper method
def some[A](a: A): Option[A] = Some(a)
println(fmap (Bar(): Foo[Int])((_: Int) + 1))
Scala infers types like Functor[Bar] and Functor[Some] without those workarounds.
Why is that? Could anyone please point me to the section in the language spec that defines this behavior?
Regards,
raichoo
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您要求编译器执行两项任务:
fmap
的类型参数的本地类型推断 (§6.26.4),以及隐式搜索隐式参数 (§7.2)f< /代码>。参考内容为 Scala 参考。
事情大致按以下顺序进行:
对
Functor[Some]
的隐式搜索失败;Functor[Option]
不符合要求。You're asking the compiler to perform two tasks: local type inference (§6.26.4) of the type arguments to
fmap
, and an implicit search for implicit parameter (§7.2)f
. References are to the Scala Reference.Things go in roughly this order:
The implicit search for
Functor[Some]
fails;Functor[Option]
doesn't conform.