繁体   English   中英

函数表达式的流泛型类型(箭头函数)

[英]flow generic type for function expression (arrow functions)

我通常会尝试将流函数类型与其实现分开。 我写的时候可读性稍高一些:

type Fn = string => string;
const aFn: Fn = name => `hello, ${ name }`;

而不是:

const aFn = (name: string): string => `hello, ${ name }`;

使用泛型类型时,我们可以写:

const j= <T>(i: T): T => i;

const jString: string = j('apple'); // √
const jNumber: number = j(7);       // √

但是如何将这种类型与函数表达式分开?

type H<T> = (input: T) => T;
const h:H<*> = i => i;              // --> WHAT SHOULD GO FOR '*'?

const hString: string = h('apple'); // X error
const hNumber: number = h(7);       // X error

什么应该用于* any会工作,但这不是我想要的。

在haskell中,这是一个非问题:

identity :: a -> a
identity a = a

identity "a-string" // √
identity 666        // √

flow.org/try

所以我注意到如果我使用有界泛型 ,它会起作用:

type H<T> = <T: *>(input: T) => T;
const h:H<*> = i => i;

const a: string = h('apple');      // √
const b: number = h(7);            // √
const c: {} = h({ nane: 'jon' });  // √

不要问我为什么。

 type H<T> = (input: T) => T;
    const h2:H<*> = i => i;   
    const h3:H<*> = i => i;   
    const hString: string = h3('apple');
    const hNumber: number = h2(7);

我认为你的代码和类型定义的根本问题是基于对泛型的特定属性(又称参数多态)的误解: 参数化

Parametricity声明泛型函数必须不知道有关其多态参数/返回值的类型的任何信息。 它是类型不可知的。

因此,无论具体类型如何,泛型函数都必须平等地处理与多态类型相关联的每个值。 当然,这是非常有限的。 当一个函数对它的参数一无所知时,除了不改变它之外,它不能对它做任何事情。

我们来看看一个不正确的泛型函数:

const f = <a>(x :a) :a => x + "bar"; // type error

尝试

f不会按预期键入check,因为f不能将x视为String Flow强制执行参数化。

请注意,泛型对于更高阶函数更有用。 以下是正确的通用高阶函数的示例:

type F<X, Y> = (x: X) => Y;

const apply = <X, Y>(f: F<X, Y>, x: X) :Y => f(x);

const sqr = (x :number) :number => x * x;
const toUC = (s :string) :string => s.toUpperCase();

apply(sqr, 5); // does type check
apply(toUC, "foo"); // does type check

尝试

为什么要为每种可能的类型定义特定的apply版本? 只要将fx的类型兼容,只需将其应用于任意类型的值即可。

结论

当你有一个无界泛型函数时,你可以将它应用于你想要的任何值 - 它总是按预期工作。 因此,没有理由为每种可能的类型声明一个不同的函数。 聪明的人发明了多态性以避免这种情况。

但问题仍然存在。 只要将泛型类型定义从函数声明中分离出来,Flow就不再强制执行参数:

const f = <a>(x :a) :a => x + "bar"; // type error

type G<a> = a => a;
const g :G<*> = x => x + ""; // type checks!?!

尝试

所以你的问题仍然是合理的,不幸的是,我无法为你提供食谱。 希望Flow的行为在未来版本中会发生变化。

在你自己的答案中,你建议使用有界泛型。 我不会这样做,因为它解决了根本不存在的问题,因为它似乎是对这种多态性的误用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM