Hmm, looks like Either's flatMap is not conforming...
# arrow
m
Hmm, looks like Either's flatMap is not conforming to Scalas wrt. left type: https://arrow-kt.io/docs/apidocs/arrow-core-data/arrow.core/flat-map.html vs https://www.scala-lang.org/api/2.12.0/scala/util/Either.html#flatMap[AA%3E:A,Y](f:B=%3Escala.util.Either[AA,Y]):scala.util.Either[AA,Y] Scalas left just needs to be AA >: A, whereas in ArrowKt it needs to be the same.
If it works with Kotlin, shouldn't Arrow do the same? To allow different error types sharing a common superclass.
m
Ok, so let's do it like that? 🙂
s
I don't see why not.... @Marius Kotsbak would you like to do a PR? 🙂
m
I could try yes 🙂
❤️ 1
Should try to add a test that indicate a problem today first.
s
Yes, sadly there is no function variance in Kotlin 😞 So they all need to be defined as extension functions when it's desired.
m
@simon.vergauwen hmm, is that any difference to Scala?
s
The difference is quite nuanced. In Scala it's still a concrete (virtual) method afaik, whilst in Kotlin this results in a static method. Additionally, such a static method requires an explicit (or wildcard) import. This also means there is an impact on IDEA suggesting the method since concrete methods resolve faster.
s
The current implementation in Arrow is also an extension function...
s
Is the fourth generic param needed in that case? 🤔
fun <A, B, C> EitherOf<A, B>.flatMap(f: (B) -> Either<A, C>): Either<A, C>
I can call
flatMap
on
Either<AA, B>
where
AA
is a subtype of
A
, no?
m
Yes, but not with a supertype of A.
Let's say you have ModuleError. And then Call1Error : ModuleError and Call2Error : ModuleError. Flatmap should then give ModuleError as left type.
s
Of course.
narrowing instead of widening.
m
Look at Scaladoc, it's the opposite.
s
Yes, I got the variance symbol mixed up 😅 Should've looked at Stojans snippet
m
I guess the result is that it widens to the common ancestor, which might be Any (at least in Scala)
Hmm, need to verify, but this seems to work:
Copy code
"Test" {
      open class TestSuper
      class TestSub1 : TestSuper()
      class TestSub2 : TestSuper()

      val res = Either.left(TestSub1()).flatMap { Either.left(TestSub2()) }
    }
IntelliJ says res has left type TestSuper
s
so it's already working as the Scala version?
m
Looks like it, but what magic makes it do, I'm not sure about.