Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@iravid
Copy link
Member

@iravid iravid commented Sep 16, 2019

Resolves #1682
Resolves #1676

@vasilmkd - could you have a look? Thanks!

@iravid iravid force-pushed the sink-no-separate-leftover branch 2 times, most recently from 1fd0468 to 0218383 Compare September 16, 2019 14:23
@iravid iravid force-pushed the sink-no-separate-leftover branch from 0218383 to 4f3df9d Compare September 16, 2019 15:46

s1.mergeWith(s2)(_.toString, _.toString)
.run(Sink.succeed("done"))
.run(Sink.succeed[String, String]("done"))
Copy link
Member

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.

Copy link
Member Author

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?

Copy link
Member

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! 🙏

Copy link
Member Author

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]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

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

Copy link
Member

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] =
Copy link
Contributor

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] =
Copy link
Contributor

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.

Copy link
Member Author

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.

@vasilmkd
Copy link
Contributor

vasilmkd commented Sep 16, 2019

Another day another ZSink refactor. 😆

Initial review done. I will be around for follow up changes.

Looking great.

@iravid
Copy link
Member Author

iravid commented Sep 16, 2019

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 A0 separate.

@vasilmkd
Copy link
Contributor

vasilmkd commented Sep 16, 2019

I stand by your decision. Would you be willing to fork out the takeWhile and collectAll changes?

@iravid iravid changed the title Remove ZSink's separate leftover parameter, rewrite some combinators Fixes and inference improvements to ZSink combinators Sep 17, 2019
@iravid
Copy link
Member Author

iravid commented Sep 17, 2019

@vasilmkd I moved the definitions of combinators that use A0 = A and have problematic inference into InputRemainderOps. Figured keeping the private methods on the trait was redundant.

@vasilmkd
Copy link
Contributor

vasilmkd commented Sep 17, 2019

@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. filterM.

* 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] =
Copy link
Contributor

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. 😄

Copy link
Member Author

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.

Copy link
Contributor

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]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extends AnyVal

Copy link
Member Author

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.

Copy link
Contributor

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.

Copy link
Member Author

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

Copy link
Contributor

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 {
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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 {
Copy link
Contributor

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.

Copy link
Member Author

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] =
Copy link
Contributor

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? :/

Copy link
Member Author

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
@iravid iravid force-pushed the sink-no-separate-leftover branch from a438f12 to 7841938 Compare September 17, 2019 20:06
@iravid iravid merged commit c67c924 into zio:master Sep 17, 2019
fsvehla pushed a commit to fsvehla/zio that referenced this pull request Sep 21, 2019
- Rewrite ZSink#collectAllWhileWith,collectAllN,untilOutput
- Move some combinators to implicit classes for improved inference
- Fix ZSink#takeWhile's continuation predicate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ZSink#takeWhile continuation function is wrong Refactor ZSink#collectAllWhileWith to not use stepChunk

3 participants