-
Notifications
You must be signed in to change notification settings - Fork 603
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
Segment.from will never terminate when run #1039
Comments
Also found Segment.unfold(0l)(l => Some((l, l+ 1))).take(5).drain.force.run.map(_.force.toVector) won't terminate Segment.unfold(0l)(l => Some((l, l+ 1))).take(5).drain.force.toList does as expected, unfortunately discarding the result. |
This works as expected, weird |
@mpilquist can you please tak a look? I think |
Actually I think this might be correct. val a = Segment.from(0L).take(5).drain.force.run.map(_.take(5).force.toVector)` evaluates to In fact, the scaladoc for
So if you |
@SystemFw I need somthing on segment like
this is missing. Do you think you can implement it? |
@i run in trouble when manually steping the segment in terms of uncons, that seemed to ignore certain combinators. I am trying to reproduce that, and will pos it here shortly. |
I can definitely give it a shot, could you give me a fuller signature and a few words about the expected behaviour for |
@SystemFw I need essentially same behaviour like we have on runFold in Algebra, that means : Segment[O, R] {
def runFold(b:B)(g:(B,O) => B):(R, B) = ???
} where |
Right, so you want to preserve the result of the original segment, and in addition to that, return the fold of all the output values. I'll start thinking about an implementation. |
exactly :-) you golden. |
I tried something around this lines, but somehow doesn't work well for takeWhile, @tailrec
def go[O, R](values: Segment[O, R], acc: Vector[O]): (Vector[O], R) = {
println(s">>> $values")
values.force.uncons match {
case Left(result) => (acc, result)
case Right((h, t)) => go(t, h.fold(acc)({ case (acc, o) => acc :+ o }).force.run)
}
}
val s = Segment.unfold(0)({ i => if (i < 1000) Some((i, i+ 1)) else None}).takeWhile(_ != 5, takeFailure = true)
val (b, result) = go(s, Vector.empty)
|
I think |
well that was fast :) |
@SystemFw @mpilquist thank you so much for this. |
I think this can be closed now? |
@mpilquist, @SystemFw I am still struggling to get these segments to run // complete: Segment.from(0L).filter(_ < 2).take(2).force.toList
Segment.from(0L).filter(_ < 2).take(2).fold(acc)(g).force.run Somehow the |
I think this might me a bug, and it seems to manifest only with def a = Segment.from(0L).take(5).force.toList
// res0: List[Long] = List(0, 1)
def b = Segment(1,2,3,4,5,6,7,8,9,10).filter(_ % 2 == 0).take(5).force.toList
// res1: List[Int] = List(2, 4, 6, 8, 10)
def c = Segment.from(0L).filter(_ < 2).take(5).force.toList
// hangs
def d = Segment.from(0L).map(_ + 1).take(5).force.toList
// res0: List[Long] = List(1, 2, 3, 4, 5)
def e = Segment(1,2,3,4,5,6,7,8,9,10).filter(_ % 2 == 0).takeWhile(_ < 5).force.toList
// res2: List[Long] = List(1, 2, 3, 4, 5)
def f = Segment(1,2,3,4,5,6,7,8,9,10).takeWhile(_ < 7).take(5).force.toList
// res1: List[Int] = List(1, 2, 3, 4, 5) |
@SystemFw This is consistent with which Stream tests are failing, essentially only takeWhile had a problem all others were passing ok. |
I'm getting closer to fixing this (I'm still on limited bandwidth however) |
@pchlupacek It's a bug in The bug in You can reproduce by running |
This is the problem I'm having: final def take(n: Long): Segment[O,Either[(R,Long),Segment[O,R]]] =
if (n <= 0) Segment.pure(Right(this))
else new Segment[O,Either[(R,Long),Segment[O,R]]] {
def stage0(depth: Depth, defer: Defer, emit: O => Unit, emits: Chunk[O] => Unit, done: Either[(R,Long),Segment[O,R]] => Unit) = Eval.later {
var rem = n
var staged: Step[O,R] = null
staged = self.stage(depth.increment, defer,
o => { if (rem > 0) { rem -= 1; emit(o) } else done(Right(staged.remainder.cons(o))) },
os => {
if (os.size == 0) done(Left(i-need-r-here -> rem))
else if (os.size <= rem) { rem -= os.size; emits(os) }
else {
var i = 0
while (rem > 0) { rem -= 1; emit(os(i)); i += 1; }
done(Right(staged.remainder.prepend(Segment.chunk(os.drop(i)))))
}
},
r => done(Left(r -> rem))
).value
staged.mapRemainder(_.take(rem))
} The first branch of the |
@SystemFw I don't think that's right -- if an empty chunk is emitted, we're not necessarily at the end of the segment. It's totally fine to emit n empty chunks followed by a non-empty chunk. |
@mpilquist Ah, that makes sense. I had tried using a condition of |
I think the problem might be fundamental, and can be described as:
So, cases where the source segment never calls
|
@SystemFw I think |
@mpilquist thanks for fix |
Thanks @mpilquist, I was getting stuck :) |
Program
will never terminate
Seems that any
from
variant never terminate.The text was updated successfully, but these errors were encountered: