Add Parallel type class - #1837
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1837 +/- ##
==========================================
+ Coverage 96.21% 96.22% +0.01%
==========================================
Files 272 279 +7
Lines 4628 4748 +120
Branches 124 115 -9
==========================================
+ Hits 4453 4569 +116
- Misses 175 179 +4
Continue to review full report at Codecov.
|
82b6ae7 to
714b84d
Compare
| Parallel.parTraverse(self)(f) | ||
|
|
||
| def parSequence[M[_]: Monad, F[_], B](implicit ev: A <:< M[B], P: Parallel[M, F]): M[T[B]] = | ||
| Parallel.parSequence(self.asInstanceOf[T[M[B]]]) |
There was a problem hiding this comment.
Anyone know a better solution? Feels a little bit dirty.
ef6c75c to
c5fc3ee
Compare
Summary of what this entails:Instances for:
Syntax for:
Other notes:We could also add an instance for List with an Applicative instance that zips, there currently is a newtype |
|
I will also transport cats-mtl type classes across parallel. In cats, you should also have ( |
b6d0a80 to
1836c07
Compare
|
@edmundnoble I've added the instance for it, but now I'm getting failing Serializable Tests, any pointers there? 🤔 It seems, that the instance for Otherwise, I'd just delete the ApplicativeError instance, and include it in a follow up PR, this one is already getting very large. |
|
Another open question is about an instance for |
| def applicative: Applicative[F] | ||
|
|
||
| /** | ||
| * Natural Transformation from the sequential Monad M[_] to the parallel Applicative F[_]. |
There was a problem hiding this comment.
the other way? from the parallel Applicative F[_] to the sequential Monad M[_]
| def sequential(implicit M: Monad[M]): F ~> M | ||
|
|
||
| /** | ||
| * Natural Transformation from the parallel Applicative F[_] to the sequential Monad M[_]. |
| * Some types that form a Monad, are also capable of forming an Applicative that supports parallel composition. | ||
| * The Parallel type class allows us to represent this relationship. | ||
| */ | ||
| trait Parallel[M[_], F[_]] { |
There was a problem hiding this comment.
you want extends Serializable here
|
Thank you @kailuowang! That fixed the failing tests. :) |
|
My opinion over |
|
Totally agree with you @kailuowang. CI does not pass the Validated tut tests right now because of ambiguous implicits as I feared before. I 'm not sure why it doesn't fail in the same way in the WriterT and ValidatedTests, but right now importing from We can delete the either derived |
|
The Applicative instance for Future is actually not responsible for the evaluation strategy, seeing as all Futures are already evaluated. That is to say, even if you changed Future's Applicative operations to use |
|
@LukaJCB to avoid the ambiguous implicits, an option that I can think of is to not implicitly provide the |
|
That's an excellent idea, will do! :) |
7aa9384 to
ab229b9
Compare
|
CI is happy again, I'd be fine with merging this without further functionality and deal with e.g. a List/ZipList instance afterwards :) |
52154c9 to
b311ab9
Compare
|
Now that #1885 is merged, I went ahead and added instances for NEL and NEV :) |
b311ab9 to
9493771
Compare
| val n = if (arity == 1) { "" } else { arity.toString } | ||
|
|
||
| val parMap = | ||
| if (arity == 1) s"def parMap[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = p.flatMap.map($tupleArgs)(f)" |
There was a problem hiding this comment.
is the arity=1 version tested?
| block""" | ||
| |package cats | ||
| |trait ParallelArityFunctions { | ||
| - def parMap$arity[M[_], F[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = |
There was a problem hiding this comment.
are these parMap1~22 tested?
| package tests | ||
|
|
||
| import cats.data.NonEmptyList | ||
| import cats.data.{NonEmptyList} |
There was a problem hiding this comment.
nit, no need for the braces here.
71a1239 to
0276415
Compare
0276415 to
4151e7e
Compare
johnynek
left a comment
There was a problem hiding this comment.
Looks great. One suggestion: I’d like the Parallel to require that the functors are isomorphic, not just the pure.
| */ | ||
| trait NonEmptyParallelLaws[M[_], F[_]] { | ||
| def P: NonEmptyParallel[M, F] | ||
|
|
There was a problem hiding this comment.
Should we say that the Functors should be the same. If not it seems pretty hard to reason about how they are related.
There was a problem hiding this comment.
Yes that's a good idea, I'll add a law!
kailuowang
left a comment
There was a problem hiding this comment.
This is really cool. LGTM
8dcfc4a to
4bbd46e
Compare
|
Just want to reiterate that this is awesome, great work @LukaJCB |
johnynek
left a comment
There was a problem hiding this comment.
Sorry for the review latency!
This looks really great.
|
Just wanted to drop a line to say that I'm really glad to see this PR merged 🤗 |
|
This with the opaque types SIP will be great. |
Should resolve #1830. Only Syntax and type class for now, but more to follow :)