diff --git a/core/src/main/scala/cats/data/Chain.scala b/core/src/main/scala/cats/data/Chain.scala index 3131e12066..ba94485b8a 100644 --- a/core/src/main/scala/cats/data/Chain.scala +++ b/core/src/main/scala/cats/data/Chain.scala @@ -46,6 +46,11 @@ sealed abstract class Chain[+A] { result } + /** + * Returns the head of this Chain if non empty, none otherwise. Amortized O(1). + */ + def headOption: Option[A] = uncons.map(_._1) + /** * Returns true if there are no elements in this collection. */ diff --git a/tests/src/test/scala/cats/tests/ChainSuite.scala b/tests/src/test/scala/cats/tests/ChainSuite.scala index ae58c3618b..ca7f50970f 100644 --- a/tests/src/test/scala/cats/tests/ChainSuite.scala +++ b/tests/src/test/scala/cats/tests/ChainSuite.scala @@ -56,6 +56,12 @@ class ChainSuite extends CatsSuite { } } + test("headOption") { + forAll { (s: Seq[Int]) => + Chain.fromSeq(s).headOption should ===(s.headOption) + } + } + test("size is consistent with toList.size") { forAll { (ci: Chain[Int]) => ci.size.toInt should ===(ci.toList.size)