Most discussion is on Typelevel Discord: https://discord.gg/bSQBZA3Ced
groupAdjacentBy
does most of the work, though you need a way to tunnel the A
and C
instances through. Here’s one solution which uses the hashCode of A
and C
, though hopefully you have something that’s more unique: https://scastie.scala-lang.org/zBX5mXbSRd6LYitbI9TtDA
// fs2.Stream takes 2 type parameters, expected: 1
FlatMap[fs2.Stream].flatten(???)
// fs2.Stream[fs2.Pure,Int] takes no type parameters, expected: 1
FlatMap[fs2.Stream[Pure, Int]].flatten(???)
* -> *
, so things of shape F[_]
*
one time, and of kind (* -> *) -> * -> *
the other time
* -> *
FlatMap[Stream[Pure, *]]
, where *
comes from kind projector
FlatMap[Stream[Pure, ?]]
in older versions of kind projector
*
(so shape A
), with an existential parameter (a wildcard type _
), which is a massive inconsistency syntax-wise, since at the value level _
does indeed mean "partially apply"
*
(pronounced star
or type
) is the kind of types that require no extra info to be instantiated, so A
, Int
, Stream[IO, Int]
, Stream[F, Int]
etc
F[_]
requires a type of kind *
(an A
), and produces another type of kind *
(F[A]
)
F[_]
has kind * -> *
Either
requires two types of kind star and produces types of kind star, so the kind of Either is * -> * -> *
(it's curried)
* -> * -> *
Stream[Int, Int]
, which is incorrect
* -> *
, and the second kind *
Stream
has kind (* -> *) -> * -> *
FlatMap
is (* -> *) -> *
FlatMap
expects one, it's ambiguous with * -> *
, i.e. trait Foo[A]
Stream[Pure, Int]
, of kind *
, and the F[_]
parameter, of kind * -> *
* -> *
, but Stream[Pure, Int]
has kind *
Stream[Pure, Int]
takes zero type params, but I expect it to take 1