-
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 method eitherPar to the type class CommutativeEither #372
Comments
I would like to work on this one. :) |
By this ticket, we would have an @adamgfraser in we merged #437, we would loose the ability to merge certain types in a sequential manner (like ZIO, Future, etc), which would be unfortunate. But if you really wanted Or we could drop So I see 4 options:
@adamgfraser @jdegoes so what do you guys think, which would you prefer? Or do you see some other option? |
So I think we definitely want the ability to support both commutative and non-commutative combining operations, and those are important even for data types that don't do actual concurrency (e.g.
trait Validation[+E, +A]
object Validation extends LowPriorityValidationImplicits {
def validationIdentityBoth[E]: IdentityBoth[Validation[E, _]] = ???
}
trait LowPriorityValidationImplicits {
def validationCommutativeBoth[E]: CommutativeBoth[Validation[E, _]] = ???
} This results in summoning
Just like we introduced new types like
I think this definitely works but I worry that it is the best design. We are conflating two different operations, sequential combination and parallel combination, that don't necessarily have any relationship to each other. I don't think there are really well defined laws that describe how I am inclined to go with the first option. |
I do like using "priority" to choose between commutative and non-commutative. The main problem is the clash. There is no way to define both associative (non-commutative) and associative (commutative) together (i.e. coherently). Maybe that matters less with Scala 3. Another possibility is the newtyping. With curried type constructors, you could imagine doing Overall, priority seems the least risky. |
Alright, keeping separate instances of
Btw, for |
Sounds good. The only thing I would add is I don't think that is accurate with regard to |
Difficulty: Easy, familiarity with the Type class design pattern is an advantage
After adding
eitherPar
toCommutativeEither
, implement it for all the types implementing the Type class. The signature is like this.Make sure, that the other helper and extension methods (like
orElseEitherPar
) inCommutativeEither
useeitherPar
instead of justeither
. Note, that for some types,eitherPar
can be the same implementation aseither
.As a stretch goal, move the
CommutativeEither
instances (all that can be, which are all in this case) to the supre-classes'AssociativeEither
companion object. Read about the reasoning where to put Type class instance and the Implicit scope in this article https://meta.plasm.us/posts/2019/09/30/implicit-scope-and-cats/As a stretch goal # 2, add tests for missing instances to
CommutativeEitherSpec
(tests for some basic instances, likeOption
orList
are already present).The text was updated successfully, but these errors were encountered: