了解 Ramda.js

Understanding Ramda.js

问题一:

   var _curry1 = function _curry1(fn) {
        return function f1(a) {
            if (arguments.length === 0) {
                return f1;
            } else if (a != null && a['@@functional/placeholder'] === true) {
                return f1;
            } else {
                return fn.apply(this, arguments);
            }
        };
    };

检查 a['@@functional/placeholder'] === true 的目的是什么?

问题二:

http://ramdajs.com/0.18.0/docs/#reduce

如何阅读符号?

(a,b -> a) -> a -> [b] -> a

第一次看到这样的写法,从哪里来的?

问题 2:

这是 Hindley-Milner 类型的签名。对于给出的示例,'a' 和 'b' 是任意类型,'->' 是一个函数。

所以让我们分解一下。

首先,我们取一个类型 'a' 和一个函数 'b -> a'

(a, b -> a)

This returns a function, which returns a function,.. (cause you know, currying).重点是我们可以添加“()”以使其更具可读性。

(a, b -> a) -> (a -> ([b] -> a))

因此,如果您传递此函数 'a' 和一个函数 'a' -> 'b',您将返回

a -> ([b] -> a)

如果你传递一个类型 'a'

[b] -> a

其中 [b] 是 'b's 类型的数组。传递这个函数 [b] 给你 类型 a

一个

如果你想在JavaScript中阅读更多关于函数式编程的内容,我可以推荐The Mostly Adequate Guide

问题一:

没有"notation"。 __.js 应该清理它:

module.exports = {'@@functional/placeholder': true};

所以@@functional/placeholder

中的foo没有区别
a = { foo: true }
a.foo
a["foo"]

(显然,你不能写 a.@@functional/placeholder,因为那里有很多奇数符号。)

在该文件中也可以看到意图:

/**
 * A special placeholder value used to specify "gaps" within curried functions,
 * allowing partial application of any combination of arguments,
 * regardless of their positions.
 *
 * If `g` is a curried ternary function and `_` is `R.__`, the following are equivalent:
 *
 *   - `g(1, 2, 3)`
 *   - `g(_, 2, 3)(1)`
 *   - `g(_, _, 3)(1)(2)`
 *   - `g(_, _, 3)(1, 2)`
 *   - `g(_, 2, _)(1, 3)`
 *   - `g(_, 2)(1)(3)`
 *   - `g(_, 2)(1, 3)`
 *   - `g(_, 2)(_, 3)(1)`
 ...

所以目的是在柯里化时能够 "skip" 一些地方。该测试决定一个参数是一个真正的参数还是 __.js 占位符,并相应地表现。为什么是@@functional/placeholder——大概正是希望它太诡异,这样才不会和任何人的合法数据发生冲突。

问题二:

该符号是类型理论中的标准符号,并由 Haskell 推广。 ab 是任何类型。 (...) 是类型的元组,[a] 是元素为a 的列表。 a -> b 是一个接受类型为 a 的参数并产生类型为 b 的 return 的函数,并且是右结合的。有问题的例子是:

It is a function that takes an argument 一个函数,它有两个参数(分别是 ab 类型)和 returns 一个 a 类型的值;并产生一个接受类型 a 参数的函数和 returns 一个接受类型为 b、return 值的元素列表的参数的函数输入 a.

这读起来很混乱,但非科里化的描述会更容易一些:它是一个接受三个参数的函数:第一个是函数(如上所述),第二个是 a,第三个是 b 元素的列表,return 是 a.

的值

具体来说,R.reduce就是这样一个函数:in

R.reduce(add, 10, numbers);

add 是一个函数,它接受两个整数(ab 是相同的整数),returns 是一个整数((a, b) -> a); 10 是整数类型 (a); numbers 是一个整数列表 ([b]); return 值是一个整数 (a)。

请注意,它混合了柯里化和非柯里化语法;如果完全柯里化,add 将是 a -> b -> a,而不是 (a, b) -> a