-
Couldn't load subscription status.
- Fork 1.4k
Add tuple syntax that includes environment types #1444
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 tuple syntax that includes environment types #1444
Conversation
f055461 to
014fe19
Compare
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.
Hi @jeremyrsmith, this looks like a great addition. We're still pre-1.0 so we're not keeping bincompat; would it be possible for you to adjust the existing syntax classes instead of introducing new ones?
014fe19 to
1063655
Compare
|
@iravid Sure, that makes it way easier. Updated to just change the existing classes and methods. |
|
|
||
| final class IOTuple2[E, A, B](val ios2: (IO[E, A], IO[E, B])) extends AnyVal { | ||
| def map2[C](f: (A, B) => C): IO[E, C] = ios2._1.flatMap(a => ios2._2.map(f(a, _))) | ||
| final class IOTuple2[E, RA, A, RB, B](val ios2: (ZIO[RA, E, A], ZIO[RB, E, B])) extends AnyVal { |
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.
Would this widen correctly to the LUB error type if left and right IO in a tuple have different error types?
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.
I'm not sure... if it already did that, it should still do that. This could probably further modified to correctly infer the error LUB, if it doesn't already, but this PR is just for allowing environment types.
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.
Yes, it should infer correctly.
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.
I tried it out and it does indeed infer the error LUB:
scala> import zio.syntax._
import zio.syntax._
scala> val a = ZIO(10)
a: zio.Task[Int] = zio.ZIO$EffectPartial@29dd4b0b
scala> val b = ZIO.succeed("hello")
b: zio.UIO[String] = zio.ZIO$Succeed@45db18dd
scala> val c = ZIO(20).refineOrDie { case err: Throwable => new IllegalArgumentException("Oh no!", err) }
c: zio.ZIO[Any,IllegalArgumentException,Int] = <function1>
scala> val all = (a, b, c).map3 {
| (i1, str, i2) => i1 + str.length + i2
| }
all: zio.ZIO[Any with Any with Any,Throwable,Int] = zio.ZIO$FlatMap@363a9244If the Any with Any with Any is bothersome, it can be solved with an additional implicit.
|
I'm not sure why test_232_jdk11_jvm failed... it seems unrelated? |
|
@jeremyrsmith indeed, I re-launched it |
|
|
||
| final class IOTuple2[E, A, B](val ios2: (IO[E, A], IO[E, B])) extends AnyVal { | ||
| def map2[C](f: (A, B) => C): IO[E, C] = ios2._1.flatMap(a => ios2._2.map(f(a, _))) | ||
| final class IOTuple2[E, RA, A, RB, B](val ios2: (ZIO[RA, E, A], ZIO[RB, E, B])) extends AnyVal { |
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 no need to use 2 different R type parameters: you can use one, and let Scala unify them. In fact, letting Scala do this initially instead of trying to force it later using with will lead to better inference.
On both this and the other tuple syntaxes, I'd go down to 1 R and let Scala do the heavy lifting...
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.
Wow, you're right @jdegoes – I'm not sure why I'm surprised that the inference works, but it works just fine that way and is much simpler. Updated the PR (if you can still call it that 😄)
1063655 to
53be328
Compare
I did this so that
.map[2|3|4]extension methods can be available on tuples which include environment types. TheRof the result is simply the intersection ofRs of the tuple elements.I made new value classes and implicit defs for this, so as to avoid any binary compatibility complications. This entailed putting the new implicit conversions in a trait to be inherited, so that they wouldn't conflict with the existing implicit defs (they should only be used when one or more tuple elements have R =!:= Any, which currently wouldn't work at all). I think this ought to be binary compatible, but to be honest I'm not 100% sure.