Функциональный объект — Википедия

Функциональный объект (англ. function object), также функтор, функционал и функционоид — распространённая в программировании конструкция, позволяющая использовать объект как функцию. Часто используется как callback, делегат.

Функтором представления называется функтор (англ. functor), описывающий отображение между математическим понятием (множество, функция) и его реализацией на языке программирования (соответственно, множество, функция)[1].

В C++ функциональный объект создаётся с помощью класса, у которого перегружен operator():

class compare_class {   public:   bool operator()(int A, int B) const {     return (A < B);   } };  // объявление функции сортировки template <class ComparisonFunctor>  void sort_ints(int* begin_items, int num_items, ComparisonFunctor c);  int main() {     int items[] = {4, 3, 1, 2};     compare_class functor;     sort_ints(items, sizeof(items)/sizeof(int), functor); } 

Кроме того, в качестве функционального объекта можно использовать указатель на функцию.

В JavaScript функция является объектом:

const acc = function (add) { acc.value += add; }; acc.value = 0;  acc(2); console.log(acc.value); // 2  acc(6); console.log(acc.value); // 8 

В С# и VB.NET для программирования функторов используются делегаты.

Поскольку в Java функции не являются объектами первого класса, функтор представляет собой объект, реализующий интерфейс, часто в виде безымянного вложенного класса:

List<String> list = Arrays.asList("10", "1", "20", "11", "21", "12"); 		 Collections.sort(list, new Comparator<String>() {     public int compare(String o1, String o2) {         return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));     } }); 

или лямбда-выражения:

List<String> list = Arrays.asList( "10", "1", "20", "11", "21", "12" );  Collections.sort( list, (String o1, String o2) -> 		Integer.valueOf( o1 ).compareTo( Integer.valueOf( o2 ) ) ); 

В Haskell функтором называется класс типов, который декларирует единственный метод «fmap». Интуитивно, «fmap» применяет функцию a -> b к значению типа f a, чтобы получить значение типа f b. С другой стороны, можно рассматривать «fmap» как функцию высшего порядка, преобразующую «простую» функцию a -> b в «составную» функцию f a -> f b. Важно отметить, что структура значения типа f после применения «fmap» должна оставаться неизменной.

class Functor f where     fmap :: (a -> b) -> f a -> f b 

Тривиальные примеры использования:

plusOne = (+1)  numberList = [1, 2, 3, 4, 5]  newNumberList = fmap plusOne numberList  -- newNumberList == [2, 3, 4, 5, 6]  square :: Int -> Int square = (^2)  -- | 'Set' data type requires "Data.Set" library. squareAllSetElements :: Set Int -> Set Int squareAllSetElements = fmap square 

Функтор может быть определён практически для любого параметрически полиморфного типа.

В PHP существует магический метод __invoke , который вызывается, когда скрипт пытается выполнить объект как функцию:

class Functor {     public function __invoke(int $a, int $b): bool     {         return $a < $b;     } }  $arr = [1, 5, 2, 8, 9, 0, 3];  usort($arr, new Functor()); 

В диалектах ML (Standard ML, Alice, OCaml) функтор представляет собой функцию над модулями, то есть отображение модулей в модули.

Примечания

[править | править код]
  • Функторы в STL Programmer’s Guide  (англ.)
  • Thomas Becker. STL & Generic Programming: STL Function Objects and Their Adaptors (англ.) // Dr. Dobb’s Journal. — 2002.
  • Herb Sutter. Generalized Function Pointers (англ.) // Dr. Dobb’s Journal. — 2003.
  • Описание функторов в Portland Pattern Repository  (англ.)
  • Толковый словарь по вычислительным системам / Под ред. В. Иллингуорта и др.. — М.: Машиностроение, 1990. — 560 с. — ISBN 5-217-00617-X.