1

当使用 Sanctuary 而不是 Ramda 时,我被“教授的飞盘......”中的咖喱示例所困扰。我收到错误消息:“'curry2' 最多需要三个参数,但收到了五个参数。” 而与 Ramda 一起工作正常。我确定我做错了什么,但我无法弄清楚。

按照书中的例子:

var match = curry2((what, str) => {return str.match(what);});
var hasSpaces = match(/\s+/g);
var filter = curry2((f, ary) => {return ary.filter(f);});
var f2 = filter(hasSpaces, ["tori_spelling", "tori amos"]);

我明白了

TypeError: Function applied to too many arguments
curry2 :: ((a, b) -> c) -> a -> b -> c
‘curry2’ expected at most three arguments but received five arguments.
4

1 回答 1

1

Sanctuary比Ramda严格得多。它确保函数只应用于正确数量的参数,并且参数是预期的类型。S.add(42, true),例如,是类型错误,而R.add(42, true)计算结果为43

您的问题是Array#filter将给定函数应用于三个参数(element, index, array)。hasSpaces, 但是,只需要一个参数。

解决方案是使用S.filter而不是Array#filter

const match = S.curry2((what, str) => str.match(what));
const hasSpaces = match(/\s+/g);
const f2 = S.filter(hasSpaces, ['tori_spelling', 'tori amos']);

进行此更改后,会显示另一个类型错误:

TypeError: Invalid value

filter :: (Applicative f, Foldable f, Monoid f) => (a -> Boolean) -> f a -> f a
                                                         ^^^^^^^
                                                            1

1)  null :: Null

The value at position 1 is not a member of ‘Boolean’.

See https://github.com/sanctuary-js/sanctuary-def/tree/v0.12.1#Boolean for information about the Boolean type.

S.filter期望一个谓词作为它的第一个参数。严格来说,谓词是一个返回trueor的函数falseString#match但是,返回null匹配项或匹配项数组。

解决方案是使用S.test而不是String#match

const hasSpaces = S.test(/\s+/);
const f2 = S.filter(hasSpaces, ['tori_spelling', 'tori amos']);

在这一点上, 的定义hasSpaces是如此清晰,以至于给它起一个名字没有太大的价值。我们可以将代码编写为单个表达式:

S.filter(S.test(/\s/), ['tori_spelling', 'tori amos'])

请注意,该模式可以从 简化/\s+/g/\s/。使用 时,该g标志无效S.test,并且+不是必需的,因为我们对带有空格的字符串感兴趣,但我们对计算空格不感兴趣。

于 2017-10-07T20:25:26.720 回答