这里的目的是尝试和利用函数式编程的关联性。
bailFirst
和bailLast
可以有更好的名称吗?
我认为bailFirst
看起来像是总和类型,bailLast
看起来像产品类型。
基于@Bergi注释的更新-它们返回true和string的总和数据类型
validate
带有谓词,如果有效则返回true,如果无效则返回错误消息。
[bailFirst
应该在第一次无效检查时停止
[bailLast
将运行所有检查,并将消息连接为一条消息。
const validate = (pred, msg) => x => pred(x) ? true : msg;
const bailFirst = (...fns) => x => {
for(let fn of fns) {
const valid = fn(x);
if(valid !== true) return valid;
}
return true;
};
const bailLast = (...fns) => x => {
const msgs = [];
for(let fn of fns) {
const valid = fn(x);
if(valid !== true) msgs.push(valid);
}
if(msgs.length) return msgs.join("\n");
return true;
};
const type = t => validate(x => typeof x === t, `Not a ${t}`);
const str = type('string');
const minLen = min =>
validate(v => v.length > min, `Min length is ${min}`);
const maxLen = max =>
validate(v => v.length < max, `Max length is ${max}`);
const between = (min, max) =>
bailFirst(str, minLen(min), maxLen(max));
const strong = validate(x => /strong_password/.test(x), 'Week password');
const password = bailLast(str, minLen(8), maxLen(24), strong);
const between2and4 = between(2, 4);
between2and4('foo'); // true
between2and4('foooo'); // Max length is 4
password('abc123'); // Min length is 8\nWeek password
尽管适当的命名比通常的Stackoverflow问题更主观,但我也很高兴希望画出正确的联系。
[bailFirst
有点让我想起Haskell中的all
或Scala中的forall
。将您的js重写为Haskell如下所示:
bailFirst :: a -> [a -> Bool] -> Bool
bailFirst x = all ($x)
它提早保释的事实当然很好,但是不影响函数的输出。因此,我可以称其为与all
相关的东西。
bailLast
但是实际上并不保释。似乎返回布尔值或验证错误列表,有点像堆栈跟踪?我可能会跳过任何像validateAll
之类的花哨电话。