假设我有一个函数,该函数将一个函数作为参数,并返回另一个函数,该函数将一个值传递给作为参数传递的函数:
setTimeout
是否可以使用Flow Type键入此函数,使得const curry = f => x => f(x);
的返回值由传递的函数curry
确定(如果已键入该函数)?
我尝试过:
f
传递第一个参数的结果是结果函数const numToStr = (x: number): string => x.toString();
const curry = <F: Function>(f: F): (mixed => *) => (x: mixed): * => f(x);
const curried = curry(numToStr);
具有这样的签名:
curried
这很有意义,要么结果为空,要么为空。我希望的是,因为键入了(((x: mixed) => any) | ((x: mixed) => empty))
,所以Flow可能会理解numToStr
实际上是curried
。
有没有办法做我错过的事情?如果没有,任何人都可以解释原因。
答案 0 :(得分:1)
通常 适用于以下过程:获取两个参数的函数并将其转换为一个参数的函数,该函数返回一个参数的另一个函数,该函数返回结果。
在Flow中,它看起来像这样:
const curry = <A, B, C>(f: (A, B) => C): (A => (B => C)) => (x) => (y) => f(x, y);
const prefixNum = (prefix: string, x: number): string => prefix + x.toString();
const prefixed = curry(prefixNum);
const withHello = prefixed("hello ");
const result = withHello(3); // "hello 3"
您的版本有些不同。您正在将一个参数的函数转换为零参数的函数。这更像是懒惰的求值,而不是简单的计算:提供所有参数,但仅返回零参数函数(有时称为“ thunk”),该函数实际上在调用时执行计算。该实现可能如下所示:
const makeLazy = <A, C>(f: A => C): (A => (() => C)) => (x) => () => f(x);
基本上是上面的定义,但是其中一种类型被()
取代。这应该可以按照您希望的方式工作:
const numToStr = (x: number): string => x.toString();
const lazyNumToStr = makeLazy(numToStr);
const thunk = lazyNumToStr(3);
thunk(); // "3"