cats'NonEmptyList vs scala stdlib ::

时间:2017-12-02 07:52:23

标签: scala scala-cats

我最近正在研究猫库,我遇到过这个名为NonEmptyList的类。

在阅读了api之后,我不禁想知道是什么让猫作者创建了一个新类,而不是利用内置的东西(::)并使用类型类扩展它。它甚至没有在cat github页面中列出,所以我来这里询问它。也许是因为cons是List的子类型? (虽然我不知道它的含义)

::和NEL有什么区别?为什么猫作者必须编写NEL而不是使用::?

1 个答案:

答案 0 :(得分:3)

NonEmptyList List未延伸到::的主要原因是开发者体验包含API中的假设。

首先,请注意List具有可能误导的所有方法List,并且使用更强大的假设设计更好的API变得更加困难。此外,::没有任何直接返回// 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的方法,即filterNotcollectNonEmptyList。为什么?因为通过::过滤可能意味着您过滤掉所有元素,列表可能变为空元素。

这使得整个非空抽象如此强大。通过正确使用函数输入和输出类型,您可以编码有关API的假设。 ()没有提供这种抽象。