2014-10-11 4 views
5

В Java 8 новый пакет java.util.function содержит множество функциональных интерфейсов. Документация для этого пакета (http://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html) делает несколько ссылок на «функциональные формах»:Что такое «функциональная форма» в отношении функциональных интерфейсов в Java 8?

  • Есть несколько основных функции формирует, в то числе функции (одноместный функции от Т до R), Потребителя (одноместный функции от Т до void), Predicate (унарная функция от T до boolean) и поставщик (функция nilary для R).
  • Функциональные формы имеют естественную сущность, основанную на том, как они наиболее часто используются. Базовые фигуры могут быть изменены префиксом arity, чтобы указать другую значимость, такую ​​как BiFunction (двоичная функция от T и от U до R).
  • Есть дополнительная функция получена формирует, которые проходят основной функции формирует, в том числе UnaryOperator (расширяет функции) и BinaryOperator (распространяется BiFunction).

Я никогда не слышал о термине «форма функции» раньше, и я едва могу найти ссылку на него в любом месте, кроме как в приведенной выше документации, но поскольку это официальная документация Oracle по функциональным интерфейсам, я бы хотел понимать это.

Может ли кто-нибудь дать определение «формы функции» и придумать пример? Это общий термин в области компьютерных наук, или он относится только к Java 8? И как форма функции связана с дескриптором функции (например, (T) -> boolean для предиката T >)?

ОБНОВЛЕНИЕ Два комментария ниже от Брайана Гетца отвечают на вопросы, поднятые мной в этом сообщении.

+0

Единственной (неофициальная) ссылка на форму в JLS находится в нижней части [15.12.2.1] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1). – assylias

+0

«форма» также упоминается в [JSR 335] (https://jcp.org/aboutJava/communityprocess/final/jsr335/index.html), часть F; но он всегда помещается в кавычки, и для него нет явного определения. – stakx

+0

Ссылки в JLS и JSR335 на «shape» находятся в одинаковых предложениях, и ссылка, по-видимому, копируется из одного документа в другой. Из контекста кажется, что «форма функции» как-то связана с оценкой времени выполнения (тогда как «дескриптор функции», очевидно, известен при компиляции). – skomisa

ответ

2

Функция форма является в основном то, что его входы и выходы выглядят, с точки зрения параметров типа:

  • Унарный функция принимает один входной сигнал и возвращает один выход [Т → R]
  • Двоичный функция принимает два входа и возвращает один выходной [(T, U) → R]
  • тернарная функция принимает три входа и возвращает один выходной [(Т, U, V), → R]
  • поставщика (также известный как нулевая функция) принимает нет ввода и возвращает один выходной [() → R]
  • Потребитель принимает один входной сигнал и не возвращает никакого вывода [T →()]
  • Унарный предикат принимает один входной сигнал и возвращает один выходной сигнал логического типа [ Т → BOOL]
  • Бинарный предикат принимает два входа и возвращает один выход логического типа [(Т, U) → BOOL]
  • унарный оператор принимает один входной сигнал и возвращает один выход одного и того же типа [Т → Т ]
  • Бинарный оператор принимает два входа одного типа и возвращает один вывод того же типа тип [(T, T) → T]

Существует много других форм, но это обычные.

+1

Но если бы это было так, функция и предикат имели бы ту же форму: они оба берут один вход и возвращают один выход [1 → 1]. Однако приведенная выше документация явно описывает эти интерфейсы как имеющие разные формы. Вы можете быть на правильных строках, но я не уверен, что типы можно игнорировать. – skomisa

+2

@skomi Это правда, возможно, лучше всего перевести типы в дискуссию. Тем более, что существуют общие унарные функции ('T -> U'), предикаты (' T -> bool') и операторы ('T -> T'), каждый из которых отличается друг от друга. Лемм изменил мой пост. –

+0

@stakx. Ваше определение похоже на «дескриптор функции», как определено в JSR335: «Функциональный дескриптор функционального интерфейса I - это параметры типа типа метода, формальные типы параметров, типы возвращаемых данных и типы бросков, которые могут быть используемый для юридического переопределения абстрактного метода (ов) I ". Это нормально, но вызывает вопрос: в чем разница между «формой функции» и «функцией дескриптора»? – skomisa

2

Я не нашел ссылки на официальное или общепринятое определение термина «форма функции», поэтому следующее следует моей интерпретации.

А «функция форма», как представляется, его "type signature" including the return type, то есть описание сумматорного:

  • упорядоченный список/кортеж типов его параметров, и
  • типа возвращаемого значения

(То есть, в основном все о функции, кроме имени функции, имен параметров и тела.) Я подозреваю, что они не использовали термин «подпись», потому что он уже имеет другое значение в Java —, он не включает Возврат тип. Поэтому они придумали новый термин.

В функциональных языках программирования «подпись типа» обычно включает тип возврата. Подписи полезны для понимания того, что может делать функция, поэтому они часто записываются явно. Например, подпись (или «форма функции» в терминах Java) для нового BiFunction может быть записана как (T, U) -> R, где первая часть представляет собой кортеж, представляющий список параметров, а вторая часть - тип возвращаемого значения.

Поэтому я не согласен с this other answer: Я думаю, что типы материи и не предрешенным. Если бы они были отклонены, то несколько типов, определенных в этом новом пространстве имен, имели бы точно такую ​​же функциональную форму (например, Supplier, Predicate, Function). Если бы это было так, то почему в документации было бы предложено объяснить эти новые типы с несовпадающей концепцией форм функций? Это не имеет смысла. (С тех пор ответ был отредактирован.)

Вот еще несколько примеров подписей функционального типа для новых функциональных интерфейсов Java:

BiFunction<T,U,R>,   (T, U) -> R 
BinaryOperator<T,U,R>   (T, U) -> R 
BiPredicate<T,U>    (T, U) -> boolean 
Consumer<T>     T  ->()   note: `()` means `void` 
Function<T,R>     T  -> R 
IntFunction<R>    int -> R 
Predicate<T>     T  -> boolean 
Supplier<R>     ()  -> R 
UnaryOperator<T,R>   T  -> R 
+1

Вы имели в виду "T, U -> R" вместо "T -> U -> R"? – skomisa

+2

@skomi Да, это (T, U) -> R, но для людей, которые привыкли использовать языки каррирования (например, Haskell), действительно было бы T-> U-> R. –

+1

@skomi: Я удалил ту часть моего ответа, в то же время. Нет, я на самом деле имел в виду «T -> U -> R», поскольку функциональные языки прогромминга обычно позволяют выполнять каррирование, и я вообще говорил о функциональном программировании. Но поскольку currying не относится к Java, ваше предложение '(T, U) -> R' действительно было бы более подходящим. Спасибо за исправление! – stakx

 Смежные вопросы

  • Нет связанных вопросов^_^