I'm trying to write a generic map function that can work with any Functor
that looks like this:
interface Functor<A> {
map <B>(fn: (a: A) => B): Functor<B>;
inspect (): string;
}
function map2<X, Y, F1 extends Functor<X>, F2 extends Functor<Y>> (fn: (a: X) => Y) {
return function $map (functor: F1): F2 {
return functor.map(fn);
}
}
However, when I write this to try and enforce the idea that map will take a functor of one type and return a functor of a (perhaps) different type, I get the following error:
Type 'Functor<Y>' is not assignable to type 'F2'.
'Functor<Y>' is assignable to the constraint of type 'F2', but 'F2' could be instantiated with a different subtype of constraint 'Functor<Y>'
From what I understand after reading this answer, this error is telling me that after calling functor.map(fn)
I could end up with a functor that isn't the same as the one that went in?
If this is the case, how can I write this to enforce that (e.g. I put a Maybe<A>
in, I get a Maybe<B>
out instead of an Either<B>
or something). Do I need to move some of these constraints to the Functor
interface?
If that isn't what is happening, what is, and how can I address it?