3

问题一:

   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什么?

问题2:

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

我如何阅读符号?

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

这是我第一次看到这样的符号,它来自哪里?

4

2 回答 2

2

问题一:

没有“符号”。__.js应该清除它:

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

所以与in@@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)`
 ...

所以目的是在currying时能够“跳过”一些地方。测试决定一个参数是真正的参数还是__.js占位符,并据此执行。为什么会这样@@functional/placeholder- 大概正是因为希望它太怪异,因此不会与任何人的合法数据发生冲突。

问题2:

该符号在类型论中是标准的,并由 Haskell 推广。a并且b是任何类型。(...)是一个类型的元组,[a]是一个列表,其元素是a. a -> b是一个接受类型参数a并产生类型返回的函数b,并且是右关联的。有问题的示例如下:

它是一个接受参数的函数,一个接受两个参数(类型ab分别)并返回类型值的函数a;并产生一个函数,该函数接受一个类型的参数a并返回一个函数,该函数接受一个参数,该参数是一个类型的元素列表b,返回一个类型的值a

这读起来很容易混淆,但不带柯里化的描述会更容易一些:它是一个接受三个参数的函数:第一个是函数(如上所述),第二个是 的值a,第三个是列表的b元素,并返回 的值a

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

R.reduce(add, 10, numbers);

add是一个函数,它接受两个整数(两者都a相同b,整数),并返回一个整数 ( (a, b) -> a);10是整数 ( a) 类型;numbers 是一个整数列表 ( [b]);并且返回值是一个整数 ( a)。

请注意,它混合了 curried 和 uncurried 语法;如果完全咖喱,add将是a -> b -> a,不是(a, b) -> a

于 2015-10-15T07:33:13.893 回答
1

问题2:

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

所以让我们分解一下。

首先,我们采用类型“a”和函数“b -> a”

(a, b -> a)

这返回一个函数,它返回一个函数,..(因为你知道,currying)。关键是我们可以添加 '()' 使其更具可读性。

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

所以如果你传递这个函数'a'和一个函数'a' -> 'b',你会回来

a -> ([b] -> a)

如果你通过这个类型'a'

[b] -> 一个

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

一个

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

于 2015-10-15T07:33:00.450 回答