Curry 在 Sanctuary 和 Ramda 之间有何不同?
How does Curry differs between Sanctuary and Ramda?
当我使用 Sanctuary 而不是 Ramda 时,我被 "Professor's Frisby..." 中的 curry 示例卡住了。我收到错误消息:“‘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.
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
需要一个谓词作为它的第一个参数。严格来说,谓词是 returns true
或 false
的函数。 String#match
,不过,returns 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
时无效,并且 +
不是必需的,因为我们对带空格的字符串感兴趣,但我们对计算空格不感兴趣。
当我使用 Sanctuary 而不是 Ramda 时,我被 "Professor's Frisby..." 中的 curry 示例卡住了。我收到错误消息:“‘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.
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
需要一个谓词作为它的第一个参数。严格来说,谓词是 returns true
或 false
的函数。 String#match
,不过,returns 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
时无效,并且 +
不是必需的,因为我们对带空格的字符串感兴趣,但我们对计算空格不感兴趣。