Pre-SIP: A New Type for Optionals and Error Handling (2)

I just realized that there’s actually another problem with putting the success type left and the error type right. Left-bias for ? makes things work for type classes like Functor[F[_]] or Monad[F[_]] where F accepts a single type parameter. But there are other type classes like Bifunctor[F[_, _]] or Bitraverse[F[_, _]] where F accepts two type parameters.

The rule as proposed now is that when F[A] is unified with X ? Y, then it should be inferred that F is [A] =>> A ? Y and A is X.
Should we have another rule that says that when F[A, B] is unified with X ? Y, then we infer thatF is [A, B] =>> B ? A and A is Y and B is X? And if we do that, have we covered all important cases? Probably not because while that works when F is inferred, it’s ugly when you need to specify it explicitly.

I’m also wondering what swapping the type parameters around is even meant to achieve. The SIP reads as follows:

Right biased higher-kinded type inference was arguably a design mistake caused by overfitting to the Either type and blindly copying Haskell. In Haskell, right bias makes sense because type parameters are curried, but in Scala and most other languages it feels unnatural.

I find this entirely unconvincing. All these claims about a “design mistake”, “overfitting to the Either type” and “blindly copying Haskell” are mere assertions without any attempt at justification other than that it “feels unnatural”. It never felt unnatural to me, and why would it? Literally appealing to feelings is not what I would consider a well-substantiated point. What I find much more important is that we now have a library ecosystem that grew around the current convention of putting the error type left, and that’s not going away any time soon. We have IO[E, A] in ZIO, Ior[E, A] and Validated[E, A] in cats, and it should be possible to write a function that works with all of these and also ? by means of a type class like Bifunctor.

Is it just about the syntactic nicety of being able to write the type of the successful case first? If that’s the goal, then we could also solve this on a purely syntactic level: have different desugaring rules for A ? E than for other infix type constructors. A X B normally desugars to X[A, B], but we could easily have A ? E desugar to ?[E, A] instead of ?[A, E]. That would get rid of the type inference kludge and ensure interoperability with current ecosystem practice.

9 Likes