这是我尝试键入一个可能的函数器(实现是从Frisby博士的改编而来):
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 });
}在地图中,我得到了这个错误:
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>'.在join中,我得到了这个:
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.请帮助我理解这些错误,并为我指明正确的方向。
发布于 2020-07-14 14:00:07
这一切都是错误的:
map: <S>(fn: (x: T) => S) => T extends null | undefined ? Maybe<S> : Maybe<T>;我想你的意思是
map: <S>(fn: (x: T) => S) => T extends null | undefined ? Maybe<T> : Maybe<S>;因为如果T扩展null | undefined,那么可能的全部意义就是停止计算。无论哪种方式,在程序执行之前,您所做的都是要求typescript计算一个可能实例是否为空。这不是使用“可能”的目的,也不会带来任何好处。我建议编写一个类型,它可能表示类型A的存在或空类型的存在,与您的map类型分开
示例实现:
type Some<A> = { _tag: 'some', val: A };
type None = { _tag: 'none' };
// this is the lazy way to express T extends null | undefined ? Maybe<T> : Maybe<S>;
// we dont care about computing it while writing a program, only that the program handles
// the none type
export type Maybe<A> = Some<A> | None;
const Some = <A>(a): Maybe<A> => ({ _tag: 'some', val: a });
const None = <A = unknown>(): Maybe<A> => ({ _tag: 'none' });
const isNone = <A = unknown>(fa: Maybe<A>) => fa._tag === 'none';
// (f) => (fa) => (fb)
const map = <A, B>(f: (a: A) => B, fa: Maybe<A>): Maybe<B> =>
fa._tag === 'none' ? None() : Some(f(fa.val));
const chain = <A, B>(f: (a: A) => Maybe<B>, fa: Maybe<A>): Maybe<B> =>
fa._tag === 'none' ? None() : f(fa.val);
export const Maybe = {
Some,
None,
isNone,
map,
chain,
};https://stackoverflow.com/questions/62014261
复制相似问题