scala - 为什么方法参数 F 可以与类型构造函数 F 同名?

标签 scala functional-programming typeclass

我正在看 John De Goes “FP to the Max”视频。在代码中,他做了这样的事情来获取隐式对象:

  object Program {
    def apply[F[_]](implicit F: Program[F]): Program[F] = F
  }

这是否意味着变量名 F(implicit 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

编译器不会混淆,因为值存在于 different universe 中从类型:

...there exist two separate universes, the universe of types and the universe of values. In the universe of values, we have methods which take values as arguments in round parentheses (or occasionally curly braces). In the universe of types, we have type constructors, which take types as arguments in square brackets.



在处理类型类时有时会使用此约定。它旨在传达我们只想返回解析为 F 的类型类实例。 .为避免混淆,您可以使用 ev方法你已经提出的问题,甚至
object Program {
  def apply[F[_]: Program]: Program[F] = implicitly[Program[F]]
}

作为旁注,这个技巧与 apply typeclass 的伴生对象中的方法允许我们避免使用 implicitly ,例如,给定
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]]

关于scala - 为什么方法参数 F 可以与类型构造函数 F 同名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59162955/

相关文章:

scala - 从输入参数基于特征的 scala 函数返回新的修改后的字段对象

haskell - Haskell 中的 CPU 模拟、函数式数据结构,也许还有 zipper ?

scala - “functions are first class values”这到底是什么意思?

scala - 为什么 Scala 没有 IO Monad?

syntax-error - idris 接口(interface)语法

Haskell 使用 UArray 实现数据类型 Show

java - 用于正则表达式的引用/转义路径

python - 从任务中调用 Java/Scala 函数

Java GIS 和 openlayers

haskell - 是否可以将其他类型变量引入父类(super class)约束?