I've been working on implementing a Maybe functor, inspired by Dr. Frisby's approach. Here is my code:
interface Maybe<T> {
isNothing: () => boolean;
map: <S>(fn: (x: T) => S) => T extends null | undefined ? Maybe<S> : Maybe<T>;
join: <S>(fn: (x: T) => S) => T | S;
chain: <S>(fn: (x: T) => S) => T | S;
}
function Maybe<T>(x): Maybe<T> {
const instance = {};
const isNothing = () => x === null || x === undefined;
const map = <S>(fn: (x: T) => S): T extends null | undefined ? Maybe<S> : Maybe<T> => isNothing() ? Maybe<T>(x) : Maybe<S>(fn(x));
const join = () => isNothing() ? Maybe<T>(x) : x;
const chain = <S>(fn: (x: T) => S) => (instance as Maybe<T>).map(fn).join();
return Object.assign(instance, { isNothing, map, join, chain });
}
When I try to use the map function, I encounter this error message:
Type 'Maybe<T> | Maybe<S>' is not assignable to type 'T extends null ? Maybe<S> : Maybe<T>'.
Type 'Maybe<T>' is not assignable to type 'T extends null ? Maybe<S> : Maybe<T>'.
Similarly, in the join function, I am facing this issue:
This expression is not callable.
Each member of the union type '(<S>(fn: (x: T) => S) => T | S) | (<S>(fn: (x: S) => S) => S | S)' has signatures, but none of those signatures are compatible with each other.
I would appreciate any guidance in understanding these errors and finding a solution.