22
22
package fs2
23
23
package concurrent
24
24
25
- import cats .data .OptionT
26
25
import cats .kernel .Eq
27
26
import cats .effect .kernel .{Concurrent , Deferred , Ref , Resource }
28
27
import cats .effect .std .MapRef
@@ -624,27 +623,18 @@ object SignallingMapRef {
624
623
625
624
private [concurrent] trait SignalInstances extends SignalLowPriorityInstances {
626
625
implicit def applicativeInstance [F [_]: Concurrent ]: Applicative [Signal [F , * ]] = {
627
- def nondeterministicZip [A0 , A1 ](xs : Stream [ F , A0 ], ys : Stream [ F , A1 ]) : Stream [ F , ( A0 , A1 )] = {
628
- type PullOutput = ( A0 , A1 , Stream [ F , A0 ], Stream [ F , A1 ])
629
-
630
- val firstPull : OptionT [ Pull [ F , PullOutput , * ], Unit ] = for {
631
- firstXAndRestOfXs <- OptionT (xs.pull.uncons1.covaryOutput[ PullOutput ])
632
- (x, restOfXs) = firstXAndRestOfXs
633
- firstYAndRestOfYs <- OptionT (ys.pull.uncons1.covaryOutput[ PullOutput ] )
634
- (y, restOfYs) = firstYAndRestOfYs
635
- _ <- OptionT .liftF {
636
- Pull .output1[ F , PullOutput ]((x, y, restOfXs, restOfYs)) : Pull [ F , PullOutput , Unit ]
626
+ def nondeterministicZip [A0 , A1 ](
627
+ x0 : A0 ,
628
+ xs : Stream [ F , A0 ],
629
+ y0 : A1 ,
630
+ ys : Stream [ F , A1 ]
631
+ ) : Stream [ F , ( A0 , A1 )] =
632
+ xs.either (ys)
633
+ .scan((x0, y0)) {
634
+ case ((_, rightElem), Left (newElem)) => (newElem, rightElem)
635
+ case ((leftElem, _), Right (newElem)) => (leftElem, newElem)
637
636
}
638
- } yield ()
639
-
640
- firstPull.value.void.stream
641
- .flatMap { case (x, y, restOfXs, restOfYs) =>
642
- restOfXs.either(restOfYs).scan((x, y)) {
643
- case ((_, rightElem), Left (newElem)) => (newElem, rightElem)
644
- case ((leftElem, _), Right (newElem)) => (leftElem, newElem)
645
- }
646
- }
647
- }
637
+ .drop(1 )
648
638
649
639
new Applicative [Signal [F , * ]] {
650
640
override def map [A , B ](fa : Signal [F , A ])(f : A => B ): Signal [F , B ] = Signal .mapped(fa)(f)
@@ -654,7 +644,9 @@ private[concurrent] trait SignalInstances extends SignalLowPriorityInstances {
654
644
def ap [A , B ](ff : Signal [F , A => B ])(fa : Signal [F , A ]): Signal [F , B ] =
655
645
new Signal [F , B ] {
656
646
def discrete : Stream [F , B ] =
657
- nondeterministicZip(ff.discrete, fa.discrete).map { case (f, a) => f(a) }
647
+ Stream .resource(getAndDiscreteUpdates).flatMap { case (a, updates) =>
648
+ Stream .emit(a) ++ updates
649
+ }
658
650
659
651
def continuous : Stream [F , B ] = Stream .repeatEval(get)
660
652
@@ -666,7 +658,7 @@ private[concurrent] trait SignalInstances extends SignalLowPriorityInstances {
666
658
667
659
private [this ] def getAndDiscreteUpdatesImpl =
668
660
(ff.getAndDiscreteUpdates, fa.getAndDiscreteUpdates).mapN { case ((f, fs), (a, as)) =>
669
- (f(a), nondeterministicZip(fs , as).map { case (f, a) => f(a) })
661
+ (f(a), nondeterministicZip(f, fs, a , as).map { case (f, a) => f(a) })
670
662
}
671
663
}
672
664
}
0 commit comments