fs2
fs2 copied to clipboard
Type inference failing 3.2.8
trafficstars
Before 3.2.8 the following used to compile as is:
/** Buffer until `f` returns true
* @note
* Careful on unbounded memory growth
*/
extension [F[_]: Applicative, A](src: fs2.Stream[F, A])
def bufferUntil(f: A => Boolean): Stream[F, Chunk[A]] = {
def loop(s: Stream[F, (A, Boolean)], acc: Chunk[A]): Pull[F, Chunk[A], Unit] =
s.pull.uncons1.flatMap {
case Some(((a, true), tl)) => Pull.output1(acc ++ Chunk.singleton(a)) >> loop(tl, Chunk.empty)
case Some(((a, false), tl)) => loop(tl, acc ++ Chunk.singleton(a))
case None => Pull.output1(acc).whenA(acc.nonEmpty)
}
loop(src.map(x => x -> f(x)), Chunk.empty).stream
}
Scastie link: https://scastie.scala-lang.org/4JW4H1XbQHWYh8BjScmfxw
The compiler error:
Could not find an instance of Applicative for ([R] =>> fs2.Pull[Nothing, fs2.Chunk[A], R]).
I found:
cats.Invariant.catsApplicativeForArrow[([O, R] =>> fs2.Pull[Nothing, O, R]),
fs2.Chunk[A]
](/* missing */summon[cats.arrow.Arrow[[O, R] =>> fs2.Pull[Nothing, O, R]]])
But no implicit values were found that match type cats.arrow.Arrow[[O, R] =>> fs2.Pull[Nothing, O, R]].
One of the following imports might make progress towards fixing the problem:
import fs2.Compiler.Target.forConcurrent
import fs2.Compiler.Target.forSync
This can now be fixed by manually specifying the types by changing the last line to:
case None => Pull.output1[F, Chunk[A]](acc).whenA(acc.nonEmpty)
Haven't had a chance to check yet but I suspect this is caused by https://github.com/typelevel/fs2/commit/4ee6fbab6df32bc8613dceba5a8fef5f9723f433
Might also be related to https://github.com/lampepfl/dotty/issues/14640
@mpilquist Should we, for the sake of usability (type inference) revert the commit in question? They were not so unnecessary after all.