Я предполагаю, что использование partial
здесь не относится к функциональной концепции программирования частичных функций.
Рассматривая ваши примеры, операции с a
взятые вместе являются только Потребителем, так как они не возвращают никаких значений. Ваша многоразовая лямбда может быть объявлена как это:
Consumer<A> partial = a -> {
a.doSomething();
a.doAnotherThing();
}
Чтобы создать функцию, которая первый вызывает потребитель, вы можете сохранить этот помощник под рукой:
static <T,U,R> BiFunction<T,U,R> acceptAndThen(Consumer<T> c, Function<U,R> f){
return (t,u) -> {
c.accept(t);
return f.apply(u);
};
}
, которые вы могли бы использовать, чтобы составить функцию, эквивалентный исходная функция, как это (я не знаю, b.doSomething()
«s тип возврата, я буду считать, C):
BiFunction<A,B,C> f1 = acceptAndThen(partial, B::doSomething); // equivalent to (a, b) -> { partial.accept(a); return b.doSomething(); }
Ваш второй пример, который показывает, как можно повторно использовать partial
иначе, выиграют от другого помощника, который преобразует Consumer<T>
к Function<T,T>
, возвращая T
что Consumer<T>
прооперировал:
static <T> Function<T,T> returnSelf(Consumer<T> consumer){
return t -> {
consumer.accept(t);
return t;
};
}
Таким образом, вы можете создать свой второй пример, как это:
Function<A,A> f2 = returnSelf(partial); // equivalent to (a) -> { partial.accept(a); return a; }
Эти композиции не входят в стандартную библиотеку, но вы обнаружите, что такие интерфейсы, как Consumer
и Function
, имеют встроенные функции для компоновки существующих функциональных типов в новые. Например, Consumer
имеет функцию andThen
, которая может вызывать последовательные вызовы потребителей. Использование частичного изображения может отличаться
Consumer<A> partial = ((Consumer<A>) A::doSomething).andThen(A::doAnotherThing);
Несомненно. Что тебя останавливает? –
... Я не знаю как? Я не знаю, как выглядит правильный код: – Andrew
Он будет выглядеть точно так же, как вы уже предложили. Просто напишите метод 'partial (a)'. –