Let's try an even simpler example:
data Foo x = Bar
foobar :: Foo a -> Foo b
foobar f = f
Take a look at the definition of Foo. There's a type variable on the left-hand side (x), which never actually appears anywhere on the right-hand side. This is an example of a so-called "phantom type variable". There's a type in the type signature which doesn't actually correspond to the type of anything in the actual value. (And this is perfectly legal, by the way.)
Now if you have the expression Just True, then since True :: Bool, then Just True :: Maybe True. However, the expression Nothing is definitely a Maybe something. But with no actual value present, there's nothing to force it to be any specific maybe-type. The type variable is phantom in this case.
We have a similar thing here; Bar :: Foo x, for any x. So you would think that our definition of foobar is legal.
And you would be wrong.
You cannot pass a value of Foo a where a value of type Foo b is expected, even if they have exactly the same run-time structure. Because the type checker doesn't care about the run-time structure; it only cares about types. As far as the type checker is concerned, Foo Int is different to Foo Bool, even though at run-time there's no observable difference.
And that is why your code is rejected.
In fact, you have to write
foobar :: Foo a -> Foo b
foobar Bar = Bar
to let the type checker know that the Bar you're outputting is a new, different Bar than the one you received as input (and hence it can have a different type).
Believe it or not, this is actually a feature, not a bug. You can write code that makes it so that (for example) Foo Int behaves differently than Foo Char. Even though at run-time they're both just Bar.
The solution, as you have discovered, is to just take your value b out of Right and then immediately put it back in again. It seems pointless and silly, but it's to explicitly signal to the type checker that the types have potentially changed. It's perhaps annoying, but it's just one of those corners of the language. It's not a bug, it's purposely designed to work this way.
defaultEither = first . constwithfirstcoming fromData.Bifunctor. I might, however, call it something likesetLeft, since there's nothing particularly defaulty aboutLeft.Right xof typeEither Int Int, is not aRight xofEither String Int.