После долгих экспериментов и косвенных попыток у меня есть решение.Я был менее успешен с именами.
Вот идея
- Ни у функционального интерфейса, ни у одного абстрактного метода нет параметра типа.
- Функциональный интерфейс получаетпотребитель с параметром типа, но с подстановочными знаками в параметре метода.
- Потребитель - просто часть внутренних объектов, но у него есть этот параметр типа.Он используется для сохранения результата, в то время как выполнение возвращается через включающую функцию.
- Потребитель сам получает функциональный интерфейс, содержащий фактический экземпляр бизнес-функции, типизированный типом.
- Существуетметод по умолчанию, который связывает вещи вместе, включая создание потребителя.
Очистить? [риторический]
Таким образом, вместо возможности писать
Fn id = arg -> arg;
мы можем по крайней мере написать
Fn id = q -> q.q(arg -> arg);
, что является лямбда-лямбдаfactory.
Кажется, у нас закончился синтаксис, и мы не можем написать что-то вроде
Fn id = Fn.Consumer::q(arg -> arg); // not valid syntax!
В целом (с основным, чтобы показать, что я не изменяю)
import java.util.concurrent.atomic.*;
@FunctionalInterface interface Fn {
interface Instance<R> {
R fn(R arg);
}
interface Consumer<R> {
void q(Instance<R> gn);
}
void consume(Consumer<?> consumer);
default <R> R fn(R arg) {
AtomicReference<R> result = new AtomicReference<>();
this.consume((Instance<R> instance) -> { result.set(instance.fn(arg)); });
return result.get();
}
}
public interface Scratch {
Fn id = q -> q.q(arg -> arg);
Fn nul = q -> q.q(arg -> null);
public static void main(String[] args) {
String idStr = id.fn("cruel");
String nulStr = nul.fn("cruel");
System.err.println(idStr);
System.err.println(nulStr);
}
}
Я не думаю Я воспользовался отсутствием здравого смысла в системе типов.
(Я, вероятно, должен добавить более сложный пример к вопросу, чтобы показать, почему выможет захотеть сделать это.)