diff --git a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala index d817b5bd5c..fc0031da30 100644 --- a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala +++ b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala @@ -261,6 +261,20 @@ sealed class NonEmptyMapOps[K, A](private[data] val value: NonEmptyMap[K, A]) { loop(head, tail).value } + def nonEmptyTraverseBoth[G[_], L, B]( + f: (K, A) => G[(L, B)] + )(implicit G: Apply[G], ordL: Order[L]): G[NonEmptyMap[L, B]] = { + def loop(h: (K, A), t: SortedMap[K, A]): Eval[G[(L, B, SortedMap[L, B])]] = + if (t.isEmpty) + Eval.now(G.map(f.tupled(h)) { case (l, b) => (l, b, SortedMap.empty[L, B](ordL.toOrdering)) }) + else + G.map2Eval(f.tupled(h), Eval.defer(loop(t.head, t.tail))) { case ((l, b), (al, ab, acc)) => + (l, b, acc + (al -> ab)) + } + + G.map(loop(head, tail).value) { case (l, b, sm) => NonEmptyMap((l, b), sm) } + } + /** * Typesafe stringification method. *