generics - Ramda 的 Flow 类型中的柯里化(Currying)函数定义

标签 generics functional-programming flowtype currying ramda.js

Ramda 的流类型有以下 curried function definitions :

  declare type __CurriedFunction1<A, R, AA: A> =
    & ((...r: [AA]) => R)
  declare type CurriedFunction1<A, R> = __CurriedFunction1<A, R, *>

  declare type __CurriedFunction2<A, B, R, AA: A, BB: B> =
    & ((...r: [AA]) => CurriedFunction1<BB, R>)
    & ((...r: [AA, BB]) => R)
  declare type CurriedFunction2<A, B, R> = __CurriedFunction2<A, B, R, *, *>

  // ...

我不明白 ____CurriedFunctionN 的必要性助手和AA , BB类型,即为什么不能CurriedFunction1<A, R>定义为:

  declare type CurriedFunction1<A, R> =
    & ((...r: [A]) => R)

最佳答案

其原因与类型差异有关。如果我说我一开始也不明白这一点,并解释一下我是如何尝试理解它的,这可能更有意义。

在类型的定义中,唯一的区别是 AA: A 表示“AA 完全是 A 或 A 的子类型”。所以我认为原因与如何将子类型视为函数的参数有关。

因此,我使用更简单的类型版本重新创建了一个简单的示例,并传入子类型作为参数:

declare type MyCurriedFunction1<A, R> =
  & ((...r: [A]) => R)

let plus2: MyCurriedFunction1<number, number> = (x) => x+2;

let y: 1 | 2 = 1;
plus2(x);

果然,这会引发错误:

18: let plus2: MyCurriedFunction1<number, number> = (x) => x+2;
                                  ^ number. This type is incompatible with
21: plus2(x);
          ^ number enum (1 | 2)

Flow 告诉我们,使用这个更简单版本的函数类型,它不能在参数上接受比 (number)。这与一个称为类型方差的想法有关,即我们何时可以安全地使用子(或 super )类型来代替彼此。维基百科有一个sort-of-readable explanation为什么数组/元组类型通常是不变的:元组可以读取(这将允许协变)或写入(这将允许逆变),因此为了安全起见,您只能使用完全相同的类型。

但是,在这种情况下,很明显我们希望我们的函数能够采用其参数类型的子类型。对于 [A] 默认情况下不会发生这种情况,它是参数的一个参数类型的元组,因此我们必须明确允许使用参数的子类型。

因此,通过像 Ramda 那样声明类型,我们现在可以将子类型作为参数传递给使用该类型的函数。

declare type __CurriedFunction1<A, R, AA: A> =
    & ((...r: [AA]) => R)
declare type CurriedFunction1<A, R> = __CurriedFunction1<A, R, *>

let plus1: CurriedFunction1<number, number> = (x) => x+1;

let x: 1 | 2 = 1;
plus1(x);

我们没有收到任何类型错误!

关于generics - Ramda 的 Flow 类型中的柯里化(Currying)函数定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45908193/

相关文章:

Java 通配符与类型参数

c# - C#泛型如何工作?

java - 我应该如何手动转换泛型类型?

clojure - 为什么 Clojure 不支持宏中的私有(private)函数?

reactjs - Flow React : Cannot create element because React. 组件 [1] 不是 React 组件

java - 使用静态嵌套类作为泛型参数

algorithm - 如何在 Clojure 算法实现中处理多个变量?

recursion - 如何导出函数段?

javascript - 当 array.map 返回错误类型并忽略 'filter' 时,流程显示错误

javascript - 具有 flowtype 的 PhpStorm 无法识别 React.Node