【问题标题】:cats' NonEmptyList vs scala stdlib ::猫的 NonEmptyList vs scala stdlib ::
【发布时间】:2020-09-30 19:03:30
【问题描述】:

我最近在学习猫图书馆,偶然发现了这门课,叫NonEmptyList

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

::NEL 有什么区别?为什么猫的作者必须写NEL而不是::

【问题讨论】:

    标签: scala scala-cats


    【解决方案1】:

    NonEmptyList 不是从 List 扩展而来的主要原因是开发人员经验在 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 的方法,即filterfilterNotcollect。为什么?因为通过NonEmptyList过滤可能意味着你过滤掉了所有元素,列表可能会变成一个空的。

    这就是使整个非空抽象如此强大的原因。通过正确使用函数输入和输出类型,您可以对 API 的假设进行编码。 :: 不提供这种抽象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-04
      • 2013-05-01
      • 1970-01-01
      • 2018-12-04
      • 2015-10-19
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多