-
Notifications
You must be signed in to change notification settings - Fork 115
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 forany and foranyPar to Traversable #392 #424
base: series/1.x
Are you sure you want to change the base?
Changes from all commits
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 |
---|---|---|
|
@@ -1200,14 +1200,6 @@ object AssociativeBoth extends LawfulF.Invariant[AssociativeBothDeriveEqualInvar | |
def both[A, B](fa: => Vector[A], fb: => Vector[B]): Vector[(A, B)] = fa.flatMap(a => fb.map(b => (a, b))) | ||
} | ||
|
||
/** | ||
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. Did you mean to delete this? 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. Yes, |
||
* The `AssociativeBoth` instance for `ZIO`. | ||
*/ | ||
implicit def ZIOAssociativeBoth[R, E]: AssociativeBoth[({ type lambda[+a] = ZIO[R, E, a] })#lambda] = | ||
new AssociativeBoth[({ type lambda[+a] = ZIO[R, E, a] })#lambda] { | ||
def both[A, B](fa: => ZIO[R, E, A], fb: => ZIO[R, E, B]): ZIO[R, E, (A, B)] = fa zip fb | ||
} | ||
|
||
/** | ||
* The `AssociativeBoth` instance for failed `ZIO`. | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,6 +64,15 @@ object IdentityBoth extends LawfulF.Invariant[DeriveEqualIdentityBothInvariant, | |
def apply[F[_]](implicit identityBoth: IdentityBoth[F]): IdentityBoth[F] = | ||
identityBoth | ||
|
||
/** | ||
* The `IdentityBoth` instance for `ZIO`. | ||
*/ | ||
implicit def ZIOIdentityBoth[R, E]: IdentityBoth[({ type lambda[+a] = ZIO[R, E, a] })#lambda] = | ||
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. Actually, could you do it the other way around? 🙏 |
||
new IdentityBoth[({ type lambda[+a] = ZIO[R, E, a] })#lambda] { | ||
def any: ZIO[R, E, Any] = ZIO.unit | ||
def both[A, B](fa: => ZIO[R, E, A], fb: => ZIO[R, E, B]): ZIO[R, E, (A, B)] = fa zip fb | ||
} | ||
|
||
def fromCovariantIdentityFlatten[F[+_]](implicit | ||
covariant: Covariant[F], | ||
identityFlatten: IdentityFlatten[F] | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -122,6 +122,30 @@ trait Traversable[F[+_]] extends Covariant[F] { | |||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Compute each element of the collection | ||||||
* with specified effectual function `f` | ||||||
* and then reduces the results using the | ||||||
* `AssociativeEither[G].both` operation, | ||||||
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.
Suggested change
|
||||||
* returning `None` if the collection is empty. | ||||||
*/ | ||||||
def forany[G[+_]: AssociativeEither: Covariant, A, B](fa: F[A])(f: A => G[B]): Option[G[B]] = { | ||||||
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. Isn't this 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. Yes, that's what I was going for! Thank you @adamgfraser , I didn't know it could have this name 👍 I was pushed to make a proposal for it, when I was looking at the signature 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. @sideeffffect Wow! That Visual Scala resource is really cool! I think we can get away with just having an 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. Yes. Good point! But in that case, we would probably need |
||||||
implicit val associative: Associative[G[B]] = Associative.make[G[B]](_ orElse _) | ||||||
reduceMapOption(fa)(f) | ||||||
} | ||||||
|
||||||
/** | ||||||
* Compute each element of the collection | ||||||
* with specified effectual function `f` | ||||||
* and then reduces the results using the | ||||||
* `CommutativeEither[G].both` operation, | ||||||
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.
Suggested change
|
||||||
* returning `None` if the collection is empty. | ||||||
*/ | ||||||
def foranyPar[G[+_]: CommutativeEither: Covariant, A, B](fa: F[A])(f: A => G[B]): Option[G[B]] = { | ||||||
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.
|
||||||
implicit val associative: Associative[G[B]] = Associative.make[G[B]](_ orElsePar _) | ||||||
reduceMapOption(fa)(f) | ||||||
} | ||||||
|
||||||
/** | ||||||
* Returns whether the collection is empty. | ||||||
*/ | ||||||
|
@@ -288,61 +312,65 @@ trait TraversableSyntax { | |||||
* Provides infix syntax for traversing collections. | ||||||
*/ | ||||||
implicit class TraversableOps[F[+_], A](private val self: F[A]) { | ||||||
def foreach[G[+_]: IdentityBoth: Covariant, B](f: A => G[B])(implicit F: Traversable[F]): G[F[B]] = | ||||||
def foreach[G[+_]: IdentityBoth: Covariant, B](f: A => G[B])(implicit F: Traversable[F]): G[F[B]] = | ||||||
F.foreach(self)(f) | ||||||
def contains[A1 >: A](a: A1)(implicit A: Equal[A1], F: Traversable[F]): Boolean = | ||||||
def contains[A1 >: A](a: A1)(implicit A: Equal[A1], F: Traversable[F]): Boolean = | ||||||
F.contains[A, A1](self)(a) | ||||||
def count(f: A => Boolean)(implicit F: Traversable[F]): Int = | ||||||
def count(f: A => Boolean)(implicit F: Traversable[F]): Int = | ||||||
F.count(self)(f) | ||||||
def exists(f: A => Boolean)(implicit F: Traversable[F]): Boolean = | ||||||
def exists(f: A => Boolean)(implicit F: Traversable[F]): Boolean = | ||||||
F.exists(self)(f) | ||||||
def find(f: A => Boolean)(implicit F: Traversable[F]): Option[A] = | ||||||
def find(f: A => Boolean)(implicit F: Traversable[F]): Option[A] = | ||||||
F.find(self)(f) | ||||||
def foldLeft[S](s: S)(f: (S, A) => S)(implicit F: Traversable[F]): S = | ||||||
def foldLeft[S](s: S)(f: (S, A) => S)(implicit F: Traversable[F]): S = | ||||||
F.foldLeft(self)(s)(f) | ||||||
def foldMap[B: Identity](f: A => B)(implicit F: Traversable[F]): B = | ||||||
def foldMap[B: Identity](f: A => B)(implicit F: Traversable[F]): B = | ||||||
F.foldMap(self)(f) | ||||||
def foldRight[S](s: S)(f: (A, S) => S)(implicit F: Traversable[F]): S = | ||||||
def foldRight[S](s: S)(f: (A, S) => S)(implicit F: Traversable[F]): S = | ||||||
F.foldRight(self)(s)(f) | ||||||
def forall(f: A => Boolean)(implicit F: Traversable[F]): Boolean = | ||||||
def forall(f: A => Boolean)(implicit F: Traversable[F]): Boolean = | ||||||
F.forall(self)(f) | ||||||
def foreach_[G[+_]: IdentityBoth: Covariant](f: A => G[Any])(implicit F: Traversable[F]): G[Unit] = | ||||||
def forany[G[+_]: AssociativeEither: Covariant, B](f: A => G[B])(implicit F: Traversable[F]): Option[G[B]] = | ||||||
F.forany(self)(f) | ||||||
def foranyPar[G[+_]: CommutativeEither: Covariant, B](f: A => G[B])(implicit F: Traversable[F]): Option[G[B]] = | ||||||
F.foranyPar(self)(f) | ||||||
def foreach_[G[+_]: IdentityBoth: Covariant](f: A => G[Any])(implicit F: Traversable[F]): G[Unit] = | ||||||
F.foreach_(self)(f) | ||||||
def isEmpty(implicit F: Traversable[F]): Boolean = | ||||||
def isEmpty(implicit F: Traversable[F]): Boolean = | ||||||
F.isEmpty(self) | ||||||
def mapAccum[S, B](s: S)(f: (S, A) => (S, B))(implicit F: Traversable[F]): (S, F[B]) = | ||||||
def mapAccum[S, B](s: S)(f: (S, A) => (S, B))(implicit F: Traversable[F]): (S, F[B]) = | ||||||
F.mapAccum(self)(s)(f) | ||||||
def maxOption(implicit A: Ord[A], F: Traversable[F]): Option[A] = | ||||||
def maxOption(implicit A: Ord[A], F: Traversable[F]): Option[A] = | ||||||
F.maxOption(self) | ||||||
def maxByOption[B: Ord](f: A => B)(implicit F: Traversable[F]): Option[A] = | ||||||
def maxByOption[B: Ord](f: A => B)(implicit F: Traversable[F]): Option[A] = | ||||||
F.maxByOption(self)(f) | ||||||
def minOption(implicit A: Ord[A], F: Traversable[F]): Option[A] = | ||||||
def minOption(implicit A: Ord[A], F: Traversable[F]): Option[A] = | ||||||
F.minOption(self) | ||||||
def minByOption[B: Ord](f: A => B)(implicit F: Traversable[F]): Option[A] = | ||||||
def minByOption[B: Ord](f: A => B)(implicit F: Traversable[F]): Option[A] = | ||||||
F.minByOption(self)(f) | ||||||
def nonEmpty(implicit F: Traversable[F]): Boolean = | ||||||
def nonEmpty(implicit F: Traversable[F]): Boolean = | ||||||
F.nonEmpty(self) | ||||||
def reduceAssociative(implicit F: Traversable[F], A: Associative[A]): Option[A] = | ||||||
def reduceAssociative(implicit F: Traversable[F], A: Associative[A]): Option[A] = | ||||||
F.reduceAssociative(self) | ||||||
def reduceIdempotent(implicit F: Traversable[F], ia: Idempotent[A], ea: Equal[A]): Option[A] = | ||||||
def reduceIdempotent(implicit F: Traversable[F], ia: Idempotent[A], ea: Equal[A]): Option[A] = | ||||||
F.reduceIdempotent(self) | ||||||
def reduceIdentity(implicit F: Traversable[F], A: Identity[A]): A = | ||||||
def reduceIdentity(implicit F: Traversable[F], A: Identity[A]): A = | ||||||
F.reduceIdentity(self) | ||||||
def product(implicit A: Identity[Prod[A]], F: Traversable[F]): A = | ||||||
def product(implicit A: Identity[Prod[A]], F: Traversable[F]): A = | ||||||
F.product(self) | ||||||
def reduceMapOption[B: Associative](f: A => B)(implicit F: Traversable[F]): Option[B] = | ||||||
def reduceMapOption[B: Associative](f: A => B)(implicit F: Traversable[F]): Option[B] = | ||||||
F.reduceMapOption(self)(f) | ||||||
def reduceOption(f: (A, A) => A)(implicit F: Traversable[F]): Option[A] = | ||||||
def reduceOption(f: (A, A) => A)(implicit F: Traversable[F]): Option[A] = | ||||||
F.reduceOption(self)(f) | ||||||
def reverse(implicit F: Traversable[F]): F[A] = | ||||||
def reverse(implicit F: Traversable[F]): F[A] = | ||||||
F.reverse(self) | ||||||
def size(implicit F: Traversable[F]): Int = | ||||||
def size(implicit F: Traversable[F]): Int = | ||||||
F.size(self) | ||||||
def sum(implicit A: Identity[Sum[A]], F: Traversable[F]): A = | ||||||
def sum(implicit A: Identity[Sum[A]], F: Traversable[F]): A = | ||||||
F.sum(self) | ||||||
def toChunk(implicit F: Traversable[F]): Chunk[A] = | ||||||
def toChunk(implicit F: Traversable[F]): Chunk[A] = | ||||||
F.toChunk(self) | ||||||
def zipWithIndex(implicit F: Traversable[F]): F[(A, Int)] = | ||||||
def zipWithIndex(implicit F: Traversable[F]): F[(A, Int)] = | ||||||
F.zipWithIndex(self) | ||||||
} | ||||||
|
||||||
|
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.
There is an existing
nothing
assertion that you can use for this.