首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何键入这个可能的functor?

如何键入这个可能的functor?
EN

Stack Overflow用户
提问于 2020-05-26 11:37:25
回答 1查看 59关注 0票数 0

这是我尝试键入一个可能的函数器(实现是从Frisby博士的改编而来):

代码语言:javascript
复制
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 });
}

在地图中,我得到了这个错误:

代码语言:javascript
复制
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中,我得到了这个:

代码语言:javascript
复制
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.

请帮助我理解这些错误,并为我指明正确的方向。

EN

回答 1

Stack Overflow用户

发布于 2020-07-14 14:00:07

这一切都是错误的:

代码语言:javascript
复制
map: <S>(fn: (x: T) => S) => T extends null | undefined ?  Maybe<S> : Maybe<T>;

我想你的意思是

代码语言:javascript
复制
map: <S>(fn: (x: T) => S) => T extends null | undefined ?  Maybe<T> : Maybe<S>;

因为如果T扩展null | undefined,那么可能的全部意义就是停止计算。无论哪种方式,在程序执行之前,您所做的都是要求typescript计算一个可能实例是否为空。这不是使用“可能”的目的,也不会带来任何好处。我建议编写一个类型,它可能表示类型A的存在或空类型的存在,与您的map类型分开

示例实现:

代码语言:javascript
复制
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,
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62014261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档