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
期望一个谓词作为它的第一个参数。严格来说,谓词是一个返回true
or的函数false
。String#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
,并且+
不是必需的,因为我们对带有空格的字符串感兴趣,但我们对计算空格不感兴趣。