繁体   English   中英

`F[_ <: A] <: B` 在类型级别和 `f: A => B` 在值级别之间的类比

[英]Analogy between `F[_ <: A] <: B` at type-level and `f: A => B` at value-level

假设F[_ <: A] <: B作为f: A => B的类型级模拟,让[F[_ <: Int] <: List[Int], A <: Int] ,那么不应该type application F[A] yield List[Int] when A = Int ,所以f(List(42))应该在以下情况下编译

$ scala3-repl
scala> def f[F[_ <: Int] <: List[Int], A <: Int](as: F[A]) = as
def f[F[_$1] <: List[Int], A <: Int](as: F[A]): F[A]

scala> f(List(42))
1 |f(List(42))
  |  ^^^^^^^^
  |Found:    List[Int]
  |Required: F[A]
  |
  |where:    A is a type variable with constraint <: Int
  |          F is a type variable with constraint <: [_$1 <: Int] =>> List[Int]

通过显式提供类型参数应用错误消息使其工作

scala> f[[_ <: Int] =>> List[Int], Int](List(42))
val res0: List[Int] = List(42)

类比在哪里中断? 考虑F[_ <: Int] <: List[Int]作为从IntList[Int]的类型级别 function 的我的心理 model 错在哪里?

首先,关于推断类型 lambdas,我认为类型推断不会 go 到提出类型 lambdas 只是为了满足约束的程度,否则直观上看起来一切都可以使用一些复杂的类型 lambda 进行类型检查,而这不会在拾取类型错误时很有用。

至于为什么f[List, Int](List(42))无法编译(因此无法推断),我们需要参考 lambdas 类型的子类型规则

假设有两种类型的 lambda

 type TL1 = [X >: L1 <: U1] =>> R1 type TL2 = [X >: L2 <: U2] =>> R2

那么TL1 <: TL2 ,如果

  • 类型区间L2..U2包含在类型区间L1..U1 (即L1 <: L2U2 <: U1 ),
  • R1 <: R2

另请注意:

部分应用的类型构造函数(例如List )被假定为等效于它的 eta 扩展。 即, List = [X] =>> List[X] 这允许将类型构造函数与类型 lambda 进行比较。

这意味着所有这些都将编译:

f[[_ <: Int] =>> List[Int], Int](List(42)) //author's compiler example
f[[_] =>> List[Int], Int](List(42)) //input type bounds can be wider, output stays the same
f[[_] =>> List[42], Int](List(42)) //input wider, output narrower
f[[x <: Int] =>> List[x], Int](List(42))//input same, output narrower

所有这些都不会:

f[[x] =>> List[x], Int](List(42)) //input type bounds can be wider but in this case it will also make the output wider
f[List, Int](List(42)) //equivalent to preceding case
f[[_ <: 42] =>> List[Int], Int](List(42)) //input type bounds cannot be narrower

如果是:

def f[F[x] <: List[x], A <: Int](as: F[A]) = as

如果您从同一类型 lambda 角度查看它f[[x] =>> List[x], Int](List(42))应该可以工作,因此f[List, Int](List(42))也可以编译(并被推断)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM