-
Couldn't load subscription status.
- Fork 1.4k
Fixes and inference improvements to ZSink combinators #1686
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
Conversation
1fd0468 to
0218383
Compare
0218383 to
4f3df9d
Compare
|
|
||
| s1.mergeWith(s2)(_.toString, _.toString) | ||
| .run(Sink.succeed("done")) | ||
| .run(Sink.succeed[String, String]("done")) |
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.
Arg. This is one of the places where it's a loss.
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.
@jdegoes Oh it's good to have the grandmaster of variance and inference here.
There's a really annoying issue that the Stream's element type parameter isn't used to infer the Sink's input type parameter - in run, transduce and others. Any thoughts on that?
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.
Can you paste signatures and I'll make it work (if it's possible 😆 )? Thank you! 🙏
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.
trait ZSink[-R, +E, A, +B]
object ZSink {
final def succeed[A, B](b: B): ZSink[Any, Nothing, A, B] = new ZSink[Any, Nothing, A, B] {}
}
trait ZStream[-R, +E, +A] {
def run[R1 <: R, E1 >: E, A1 >: A, B](sink: ZSink[R1, E1, A1, B]): Unit = ()
}
val stream = new ZStream[Any, Nothing, String] {}
stream.run(ZSink.succeed("OK"))
// cmd0.sc:11: type mismatch;
// found : ammonite.$sess.cmd0.ZSink[Any,Nothing,Nothing,String]
// required: ammonite.$sess.cmd0.ZSink[Any,Nothing,String,String]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.
@jdegoes ^
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.
Fixed in Dotty, at least
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 think this case is beyond help. The covariance on A in ZStream is interacting with the invariance on ZSink to cause the problem, and we certainly don't want to eliminate covariance on ZStream
| * Creates a sink halting with the specified `Throwable`. | ||
| */ | ||
| final def die(e: Throwable): ZSink[Any, Nothing, Nothing, Any, Nothing] = | ||
| final def die(e: Throwable): ZSink[Any, Nothing, Any, Nothing] = |
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.
Just to mark them for having Any, die, dieMessage and drain.
| * the predicate `p`. | ||
| */ | ||
| final def ignoreWhile[A](p: A => Boolean): ZSink[Any, Nothing, A, A, Unit] = | ||
| final def ignoreWhile[A](p: A => Boolean): ZSink[Any, Nothing, A, Unit] = |
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'd like this to be a SinkPure and not delegate through ignoreWhileM. Ignore if you think it's not worth it.
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.
Yeah we'll do that in a follow-up. There are several combinators that can be overriden in SinkPure.
|
Another day another Initial review done. I will be around for follow up changes. Looking great. |
|
Hmm. So, I went over the changes again and I admit I am not sold on whether the inference changes are a win or not. So I'm going to backpedal on this and keep |
|
I stand by your decision. Would you be willing to fork out the |
|
@vasilmkd I moved the definitions of combinators that use |
|
@iravid I saw that and like it a lot. Big 👍. It will take some more consideration when implementing future combinators but the removal of implicit compiler evidence is worth it in my opinion. Can I bother you to go through the tests again and try to remove as much of the type parameters as possible? Just as a testament to the improved inference. E.g. |
| * see [[ZSink.succeed]] | ||
| */ | ||
| final def succeed[B](b: B): Sink[Nothing, Nothing, Any, B] = | ||
| final def succeed[A, B](b: B): Sink[Nothing, A, A, B] = |
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.
A should be reverted now. 😄
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.
It's actually required because of the leftovers.
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.
Sorry yes, I skimmed over the implementation.
| object ZSink extends ZSinkPlatformSpecific { | ||
|
|
||
| implicit class InputRemainderOps[R, E, A, B](val sink: ZSink[R, E, A, A, B]) extends AnyVal { | ||
| implicit class InputRemainderOps[R, E, A, B](private val sink: ZSink[R, E, A, A, B]) { |
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.
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.
Can't work because of the inner classes that are defined. Not a big loss.
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.
Sorry, can you point me to the defined classes? I can't find anything.
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.
case class State in collectAllN
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, thanks.
| * Filters the inputs fed to this sink. | ||
| */ | ||
| def filter(f: A => Boolean): ZSink[R, E, A0, A, B] = | ||
| self match { |
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.
Nitpicking. Not sure how I feel about having SinkPure implementations in this file from a discoverability and maintainability standpoint.
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.
Well, since filter was moved out to an implicit class to improve inference, it can no longer be overriden in `SinkPure.
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 well aware... we'll live with it. :-)
| } | ||
| } | ||
|
|
||
| private[ZSink] object internal { |
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.
Can the Optional ADT be migrated to ? as well? OTOH Not sure if Side is used in multiple combinators.
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.
Yup! Moved it
| def stepPure(state: State, a: Any) = () | ||
| def extractPure(state: State) = Right((b, Chunk.empty)) | ||
| def cont(state: State) = false | ||
| final def succeed[A, B](b: B): ZSink[Any, Nothing, A, A, B] = |
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 guessing this cannot be inferred from the sink before this one? :/
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.
No, unfortunately not. Same problem as with ZStream#run
- Rewrite ZSink#collectAllWhileWith,collectAllN,untilOutput - Move some combinators to implicit classes for improved inference - Fix ZSink#takeWhile's continuation predicate
a438f12 to
7841938
Compare
- Rewrite ZSink#collectAllWhileWith,collectAllN,untilOutput - Move some combinators to implicit classes for improved inference - Fix ZSink#takeWhile's continuation predicate
Resolves #1682
Resolves #1676
@vasilmkd - could you have a look? Thanks!