-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add NonEmptyList#partitionE #1858
Changes from all commits
0f9cd55
47048a9
3de168a
a5cbeee
e4029ab
0a7ac70
dbd636e
120ee76
9949687
f3169aa
3c069d2
98dfc73
fc825c4
202abbc
49891e1
2510240
ed75575
e1d39b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
package cats | ||
|
||
import cats.data.NonEmptyList | ||
|
||
import cats.data.{Ior, NonEmptyList} | ||
import simulacrum.typeclass | ||
|
||
/** | ||
|
@@ -177,6 +176,34 @@ import simulacrum.typeclass | |
Reducible[NonEmptyList].reduce(NonEmptyList(hd, a :: intersperseList(tl, a))) | ||
} | ||
|
||
/** | ||
* Partition this Reducible by a separating function `A => Either[B, C]` | ||
* | ||
* {{{ | ||
* scala> import cats.data.NonEmptyList | ||
* scala> val nel = NonEmptyList.of(1,2,3,4) | ||
* scala> Reducible[NonEmptyList].nonEmptyPartition(nel)(a => if (a % 2 == 0) Left(a.toString) else Right(a)) | ||
* res0: cats.data.Ior[cats.data.NonEmptyList[String],cats.data.NonEmptyList[Int]] = Both(NonEmptyList(2, 4),NonEmptyList(1, 3)) | ||
* scala> Reducible[NonEmptyList].nonEmptyPartition(nel)(a => Right(a * 4)) | ||
* res1: cats.data.Ior[cats.data.NonEmptyList[Nothing],cats.data.NonEmptyList[Int]] = Right(NonEmptyList(4, 8, 12, 16)) | ||
* }}} | ||
*/ | ||
def nonEmptyPartition[A, B, C](fa: F[A])(f: A => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. couldn't we do this considerably more efficiently for NonEmptyList and NonEmptyVector? Can we add methods to those datatypes that does so? Eval is kind of a perf killer, sadly, which this method hides. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just had the same idea :D I already implemented a O(n) solution for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added overrides for NEL and NEV :) |
||
import cats.syntax.either._ | ||
|
||
def g(a: A, eval: Eval[Ior[NonEmptyList[B], NonEmptyList[C]]]): Eval[Ior[NonEmptyList[B], NonEmptyList[C]]] = { | ||
eval.map(ior => | ||
(f(a), ior) match { | ||
case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyList.one(c)) | ||
case (Right(c), _) => ior.map(c :: _) | ||
case (Left(b), Ior.Right(r)) => Ior.bothNel(b, r) | ||
case (Left(b), _) => ior.leftMap(b :: _) | ||
}) | ||
} | ||
|
||
reduceRightTo(fa)(a => f(a).bimap(NonEmptyList.one, NonEmptyList.one).toIor)(g).value | ||
} | ||
|
||
override def isEmpty[A](fa: F[A]): Boolean = false | ||
|
||
override def nonEmpty[A](fa: F[A]): Boolean = true | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we did define it in
Alternative
, we could add a consistency law checking this equality, but hey ... you can't always get what you want 😃There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, I don't really mind either way tbh.
We could add a test that checks if it's consistent with List#partition though 😄