Scala 为什么方法参数F可以与类型构造函数F同名?
我在看约翰·德的“FP到最高点”视频。在代码中,他这样做是为了得到隐式对象:Scala 为什么方法参数F可以与类型构造函数F同名?,scala,functional-programming,typeclass,Scala,Functional Programming,Typeclass,我在看约翰·德的“FP到最高点”视频。在代码中,他这样做是为了得到隐式对象: object Program { def apply[F[_]](implicit F: Program[F]): Program[F] = F } 这是否意味着变量名F(隐式F:Program[F]中的第一个)实际上是不同的F?这很令人困惑。他是否打算: object Program { def apply[F[_]](implicit ev: Program[F]): Program[
object Program {
def apply[F[_]](implicit F: Program[F]): Program[F] = F
}
这是否意味着变量名F(隐式F:Program[F]中的第一个)实际上是不同的F
?这很令人困惑。他是否打算:
object Program {
def apply[F[_]](implicit ev: Program[F]): Program[F] = ev
}
当返回
F
时,编译器如何知道他引用的是哪个F
?类型构造函数还是范围中的变量 例如,功能参数T
确实不同于类型参数T
def f[T](T: T): T = T
f(42) // res0: Int = 42
编译器不会混淆,因为值存在于from类型中:
…存在两个独立的宇宙,类型宇宙和
价值的宇宙。在价值的宇宙中,我们有方法
将值作为圆括号中的参数(或偶尔卷曲)
大括号)。在类型的宇宙中,我们有类型构造函数,它接受类型
作为方括号中的参数
这个约定有时在处理类型类时使用。这意味着我们只想返回为F
解析的typeclass实例。为了避免混淆,您可以使用您已经提出的ev
方法,甚至
object Program {
def apply[F[_]: Program]: Program[F] = implicitly[Program[F]]
}
作为旁注,在typeclass的伴生对象中使用apply
方法的这个技巧允许我们避免隐式地使用,例如,给定
trait Foo[T]
trait Bar[T]
trait Program[F[_]]
implicit val fooProgram: Program[Foo] = ???
implicit val barProgram: Program[Bar] = ???
object Program {
def apply[F[_]: Program]: Program[F] = implicitly
}
然后我们就可以写了
Program[Bar]
而不是
implicitly[Program[Bar]]
当返回F
时,编译器如何知道他引用的是哪个F
?类型构造函数还是范围中的变量
编译器知道一个方法/函数只能返回一个值。因此,=
后面的内容有一个类型,但不是一个类型。顺便说一句,这不是Scala特有的。事实上,对于大多数语言以及所有主流语言来说,类型和值的世界是严格分开的。例如,它在Java中的工作原理完全相同。思考一下:类t{t(t){returnt;}}
。