[英]cats' NonEmptyList vs scala stdlib ::
我最近正在研究貓圖書館,我遇到了一個叫做NonEmptyList
類。
讀完api后,我不禁想知道是什么讓cats作者創建了一個新類,而不是利用內置的東西( ::
)並使用類型類來擴展它。 連cats github頁面都沒有列出,所以才來這里問問。 也許是因為 cons 是List
的子類型? (雖然我不知道它的含義)
::
和NEL
之間有什么區別? 為什么 cat 作者必須編寫NEL
而不是使用::
?
擁有不從List
擴展的NonEmptyList
主要原因是開發人員在 API 中包含假設的經驗。
首先,請注意::
具有List
具有的所有方法,這些方法可能會產生誤導,並且它使得設計具有更強大假設的更好 API 變得更加困難。 此外, List
沒有任何直接返回::
方法,這意味着開發人員需要手動維護非空抽象。
讓我給你看一個例子,它展示了我在實踐中的意思:
// NonEmptyList usage is intuitive and types fit together nicely
val nonEmpty: NonEmptyList[Int] = NonEmptyList.of(1, 2, 3)
val biggerNonEmpty: NonEmptyList[Int] = 0 :: nonEmpty
val nonEmptyMapped: NonEmptyList[Int] = nonEmpty.map(_ * 2)
// :: has lots of problems
// PROBLEM: we can't easily instantiate ::
val cons: ::[Int] = 1 :: 2 :: 3 :: Nil // type mismatch; found: List[Int]; required: ::[Int]
val cons: ::[Int] = new ::[Int](1, ::(2, ::(3, Nil)))
// PROBLEM: adding new element to Cons returns List
val biggerCons: ::[Int] = 0 :: cons // type mismatch; found: List[Int]; required: ::[Int]
// PROBLEM: ::.map returns List
val consMapped : ::[Int] = cons.map(_ * 2) // type mismatch; found: List[Int]; required: ::[Int]
請注意, NonEmptyList
具有返回List
方法,即filter
、 filterNot
和collect
。 為什么? 因為通過NonEmptyList
過濾可能意味着過濾掉所有元素,列表可能會變成空的。
這就是使整個非空抽象如此強大的原因。 通過正確使用函數輸入和輸出類型,您可以對 API 的假設進行編碼。 ::
不提供這種抽象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.