2017-12-02 14 views
1

最近、ネコのライブラリを勉強しています。このクラスにはNonEmptyListという名前があります。cats 'NonEmptyList vs scala stdlib ::

apiを読んだあと、猫の作者が(::)でビルドされたものを利用する代わりに、新しいクラスを作成し、それを拡張するためにtypeclassesを使用するのはどうですか?それは猫githubのページにも載っていないので、私はそれについて尋ねるためにここに来ました。 consはListのサブタイプなのでしょうか? (私はそれの意味を知らないが)

::とNELの違いは何ですか?なぜ、猫の作者は::を使わずにNELを書く必要がありましたか?

答えて

3

Listから延びないNonEmptyListを有する主な理由は、APIの中の仮定を含むの現像経験あります。

最初に、::にはすべての方法があります。誤解を招く可能性があり、より強力な前提でより良い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、すなわちfilterfilterNotcollectListを返すメソッドを持っていること:

は、私はあなたに私が実際に何を意味するかを示す例をお見せしましょう。どうして? NonEmptyListでフィルタリングすると、すべての要素を除外してリストが空になる可能性があるためです。

これは、全体をにするものではありません。抽象化が非常に強力です。関数の入出力型を適切に使用することで、APIに関する前提をエンコードできます。 ::はこの抽象化を提供しません。

関連する問題