【发布时间】:2015-02-23 06:02:20
【问题描述】:
当我编写像def foo[A,B] 这样的函数时,[A,B] 到底是什么意思?我知道这是Polymorphic Method;但是你什么时候使用foo [A] 和foo [A,B]?
这是一个我不明白区别的例子。该函数编译:
def map[B](f: A => B): Stream[B] =
foldRight(empty[B])((h,t) => cons(f(h), t))
而这个没有编译。我不明白为什么不需要A,毕竟A 被f: A => B 引用:
def map[A,B](f: A => B): Stream[B] =
foldRight(empty[B])((h,t) => cons(f(h), t))
[error] ..../Stream.scala:61: type mismatch;
[error] found : h.type (with underlying type A)
[error] required: A
[error] foldRight(empty[B])((h,t) => cons(f(h), t))
(这是来自FP in Scala 练习之一)
附录
阅读答案后,我添加了一些上下文,以帮助未来的读者。该函数是在 trait 中定义的:
trait Stream[+A] {
...
def map[B](f: A => B):Stream[B] =
foldRight(empty[B])((h,t) => cons(f(h), t))
...
}
所以错误是由 type shadowing 引起的,但请参阅下面@acjay 的出色回答。
谷歌搜索 scala type shadowing 不会导致任何 scala 文档中的直接定义,这很有趣,因为正如 @travisbrown 下面所说,它是“我见过的最常见的初学者混淆来源之一”。这里有讨论:Why does Scala support shadow variables?
【问题讨论】:
-
您在哪里看到
map方法?如果它是类的成员,则类本身可能会定义A类型参数 -
您在定义
Stream[A]的类中定义map(我假设),因此抽象类型A已经定义,map只需要为函数的结果类型。 -
这意味着您正在定义一个处理您还不知道的两种不同类型的函数,并且由于您不知道它们,因此您将为它们命名(A. B) 作为占位符。您是在告诉编译器,当用户调用函数时,它应该根据使用函数的位置将 A 和 B 替换为正确的类型。
-
感谢@mucaho 和@Freidereikhs,这确实是流特征的一部分,我会更新问题以添加一些上下文。
标签: scala