簡體   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