Curry
Вы можете изменить свою функцию, поэтому вместо двух аргументов она принимает один, а затем возвращает вторую функцию, которая принимает второй аргумент. Этот известный метод известен как curry .
// maxLengthValidator :: number -> string -> boolean
const maxLengthValidator = (boundary: number) => (val: string) : boolean => {
if (val.length > boundary) return false;
return true;
};
// ... later ...
validator: maxLengthValidator(255);
Таким образом, вы можете создавать различные валидаторы, вызывая функцию: maxLengthValidator(10)
даст вам валидатор для 10 символов, которые вы можете использовать,Поскольку это функция, вы также можете просто присвоить ее переменной:
//userNameLengthValidator :: string -> boolean
const userNameLengthValidator: (val: string) => boolean = maxLengthValidator(10);
Параметры подкачки для обеспечения частичного распределения
Вместо принятия значения , а затем максимальная длина, возьми длину в первую очередь. То же самое, что и при каррировании функции, но вместо этого этот может принимать два параметра:
const maxLengthValidator = (boundary: number, val: string): boolean => {
if (val.length > boundary) return false;
return true;
};
// ... later ...
validator: maxLengthValidator.bind(this, 255);
Та же основная идея. На этот раз у вас немного больше гибкости - вы можете вызвать функцию с обоими параметрами maxLengthValidator(10, username)
или просто частично применить ее с одним. Последний производит почти то же самое, что и карри, поскольку вы все еще получаете новую функцию с той же сигнатурой:
//userNameLengthValidator :: string -> boolean
const userNameLengthValidator: (val: string) => boolean = maxLengthValidator.bind(this, 10);
Несмотря на сходство карри не является частичным применением . Кроме того, можно использовать функцию любой арности (любое количество параметров), чтобы можно было принимать один или несколько одновременно. Например, вы можете увидеть _.curry
в Lodash
function add4(a, b, c, d) {
console.log(a + b + c + d);
}
const curryAdd4 = _.curry(add4);
curryAdd4(1)(2)(3)(4);
curryAdd4(1, 2, 3, 4);
curryAdd4(1)(2, 3)(4);
curryAdd4(1, 2, 3)(4);
curryAdd4(1)(2, 3, 4);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
Частично подать заявку с заполнителем или справа
Вы можете оставить подпись как есть и просто изменить частичное заявление. Function#bind
не очень гибок, но вы можете написать свой собственный или (еще лучше) использовать библиотеку. Я снова буду использовать Lodash, так как он имеет хорошую реализацию для них:
Частичное приложение с заполнителем
Позволяет пропускать некоторых параметров при частичном применении,Таким образом, вы можете пропустить первый и просто установить второй:
const maxLengthValidator = (val, boundary) => {
if (val.length > boundary) return false;
return true;
};
//userNameLengthValidator :: string -> boolean
const usernameLengthValidator = _.partial(maxLengthValidator, _, 10);
console.log(usernameLengthValidator("usernameTooLong"));
console.log(usernameLengthValidator("user"));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
Частично применяется справа
Частично применяется начиная справа налево, поэтому сначала будет установлено boundary
:
const maxLengthValidator = (val, boundary) => {
if (val.length > boundary) return false;
return true;
};
//userNameLengthValidator :: string -> boolean
const usernameLengthValidator = _.partialRight(maxLengthValidator, 10);
console.log(usernameLengthValidator("usernameTooLong"));
console.log(usernameLengthValidator("user"));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>