Kilka razy spotkałem się z terminem „Functor” podczas czytania różnych artykułów na temat programowania funkcjonalnego, ale autorzy zazwyczaj zakładają, że czytelnik już rozumie ten termin. Rozglądanie się w Internecie dostarczyło albo zbyt technicznych opisów (patrz artykuł Wikipedii ), albo niezwykle niejasne opisy (patrz sekcja Functors na tej stronie z samouczkiem ocaml ).
Czy ktoś może uprzejmie zdefiniować termin, wyjaśnić jego użycie i być może podać przykład tworzenia i używania Functors?
Edycja : Chociaż jestem zainteresowany teorią tego terminu, mniej interesuję się teorią niż wdrażaniem i praktycznym wykorzystaniem tej koncepcji.
Edycja 2 : Wygląda na to, że zachodzi pewna cross-terminoligia: Mam na myśli w szczególności Functors programowania funkcjonalnego, a nie obiekty funkcyjne C ++.
źródło
fmap
mapuje funkcje. W grę wchodzą dwa rodzaje mapowań. Taki sposób widzenia rzeczy pomoże zrozumieć teorię kategorii (która jest bardziej ogólna). Chodzi o to, że warto zrozumieć podstawową teorię kategorii, aby pomóc nam we wszystkich zagadnieniach teorii kategorii w Haskell (funktor, monady, ...).Odpowiedzi:
Słowo „funktor” pochodzi od teorii kategorii, która jest bardzo ogólną, bardzo abstrakcyjną gałęzią matematyki. Został pożyczony przez projektantów języków funkcjonalnych na co najmniej dwa różne sposoby.
W rodzinie języków ML funktor to moduł, który przyjmuje jeden lub więcej innych modułów jako parametr. Jest uważany za zaawansowaną funkcję, a większość początkujących programistów ma z nią trudności.
Jako przykład implementacji i praktycznego zastosowania można zdefiniować ulubioną formę zrównoważonego drzewa wyszukiwania binarnego raz na zawsze jako funktor, a jako parametr przyjmie on moduł, który zapewnia:
Typ klucza do użycia w drzewie binarnym
Funkcja całkowitego uporządkowania na klawiszach
Gdy to zrobisz, możesz zawsze używać tej samej zrównoważonej implementacji drzewa binarnego. (Typ wartości przechowywanej w drzewie jest zwykle pozostawiony polimorficzny - drzewo nie musi patrzeć na wartości inne niż je kopiować, podczas gdy drzewo zdecydowanie musi być w stanie porównywać klucze i otrzymuje funkcję porównania z parametr funktora).
Innym zastosowaniem funktorów ML jest warstwowe protokoły sieciowe . Link jest do naprawdę wspaniałego artykułu grupy CMU Fox; pokazuje, jak używać funktorów do budowania bardziej złożonych warstw protokołu (takich jak TCP) na typach prostszych warstw (takich jak IP lub nawet bezpośrednio przez Ethernet). Każda warstwa jest implementowana jako funktor, który przyjmuje jako parametr warstwę pod nią. Struktura oprogramowania faktycznie odzwierciedla sposób, w jaki ludzie myślą o problemie, w przeciwieństwie do warstw istniejących tylko w umyśle programisty. W 1994 r., Kiedy ta praca została opublikowana, była to wielka sprawa.
Dla dzikiego przykładu funktorów ML w akcji można zobaczyć artykuł ML Module Mania , który zawiera publikowalny (tj. Przerażający) przykład funktorów w pracy. Aby uzyskać genialne, jasne i przejrzyste wyjaśnienie systemu modułów ML (w porównaniu z innymi rodzajami modułów), przeczytaj kilka pierwszych stron genialnego dokumentu POPL z 1994 roku autorstwa Xaviera Leroya, Typy, moduły i oddzielna kompilacja .
W Haskell i w niektórych powiązanych czystych językach funkcjonalnych
Functor
jest to klasa typów . Typ należy do klasy typu (lub technicznie rzecz biorąc, typ „jest instancją” klasy typu), gdy typ zapewnia pewne operacje o określonych oczekiwanych zachowaniach. TypT
może należeć do klasy,Functor
jeśli ma pewne zachowanie podobne do kolekcji:Typ
T
jest sparametryzowany na innym typie, który należy traktować jako typ elementu kolekcji. Rodzaj pełnej kolekcji jest wtedy cośT Int
,T String
,T Bool
, jeśli zawierający liczby całkowite, ciągi lub logicznych odpowiednio. Jeśli typ elementu jest nieznany, jest zapisywany jako parametr typua
, jak wT a
.Przykłady obejmują listy (zero lub więcej elementów typu
a
),Maybe
typ (zero lub jeden element typua
), zestawy elementów typua
, tablice elementów typua
, wszelkiego rodzaju drzewa wyszukiwania zawierające wartości typua
i wiele innych mogę wymyślić.Inną właściwością,
T
którą należy spełnić, jest to, że jeśli masz funkcję typua -> b
(funkcję na elementach), musisz mieć możliwość przyjęcia tej funkcji i wygenerowania powiązanej funkcji w kolekcjach. Robisz to za pomocą operatorafmap
, który jest wspólny dla każdego typu wFunctor
klasie typów. Operator jest przeciążony, więc jeśli masz funkcjęeven
typuInt -> Bool
, toto przeciążona funkcja, która potrafi wiele wspaniałych rzeczy:
Konwertuj listę liczb całkowitych na listę wartości logicznych
Konwertuj drzewo liczb całkowitych na drzewo boolean
Konwertuj
Nothing
naNothing
iJust 7
naJust False
W Haskell właściwość ta jest wyrażona przez podanie typu
fmap
:gdzie mamy teraz małe
t
, co oznacza „dowolny typ wFunctor
klasie”.Krótko mówiąc, w Haskell funktor jest rodzajem kolekcji, dla której jeśli otrzymasz funkcję na elementach,
fmap
zwróci ci funkcję na kolekcjach . Jak możesz sobie wyobrazić, jest to pomysł, który można szeroko wykorzystać ponownie, dlatego jest błogosławiony jako część standardowej biblioteki Haskella.Jak zwykle ludzie nadal wymyślają nowe, przydatne abstrakty, a może warto przyjrzeć się funktorom aplikacyjnym , do których najlepszym odniesieniem może być artykuł Conor McBride i Ross Paterson, zatytułowany Programowanie aplikacyjne z efektami .
źródło
then you have to be able to take that function and product a related function on collections
Miałeś na myśliproduce
zamiastproduct
?Inne odpowiedzi tutaj są kompletne, ale spróbuję wyjaśnić użycie funktora FP . Weź to jako analogię:
W przeciwieństwie do użycia wskaźnika abstrakcji funkcji w C ++, tutaj funktor nie jest funkcją; raczej jest to coś, co zachowuje się konsekwentnie, kiedy podlega funkcji .
źródło
Istnieją trzy różne znaczenia, niewiele powiązane!
W Ocaml jest to sparametryzowany moduł. Zobacz instrukcję . Myślę, że najlepszym sposobem, aby je pogłaskać jest przykład: (napisane szybko, może być błędne)
Możesz teraz szybko dodawać wiele możliwych zamówień, sposoby tworzenia nowych zamówień, łatwo wyszukiwać binarne lub liniowe nad nimi. Programowanie ogólne FTW.
W funkcjonalnych językach programowania, takich jak Haskell, oznacza to niektóre konstruktory typów (typy sparametryzowane, takie jak listy, zestawy), które można „mapować”. Mówiąc ściślej, funktor
f
jest wyposażony(a -> b) -> (f a -> f b)
. Ma to swoje źródło w teorii kategorii. Artykuł w Wikipedii, do którego linkujesz, dotyczy tego użycia.Jest to więc szczególny rodzaj konstruktora typu i ma niewiele wspólnego z funktorami w Ocaml!
źródło
W OCaml jest to sparametryzowany moduł.
Jeśli znasz C ++, pomyśl o funktorze OCaml jako szablonie. C ++ ma tylko szablony klas, a funktory działają w skali modułu.
Przykładem funktora jest Map.Make;
module StringMap = Map.Make (String);;
buduje moduł mapy, który działa z mapami z kluczem ciągowym.Nie można osiągnąć czegoś takiego jak StringMap tylko z polimorfizmem; musisz poczynić pewne założenia dotyczące kluczy. Moduł String zawiera operacje (porównanie itp.) Na całkowicie uporządkowanym typie ciągu, a funktor połączy się z operacjami, które zawiera moduł String. Mógłbyś zrobić coś podobnego z programowaniem obiektowym, ale miałbyś narzut pośredniej metody.
źródło
Masz kilka dobrych odpowiedzi. Wrzucę:
Funkt, w sensie matematycznym, jest szczególnym rodzajem funkcji algebry. Jest to minimalna funkcja, która odwzorowuje algebrę na inną algebrę. „Minimalność” wyraża się w prawach funktora.
Są na to dwa sposoby. Na przykład, listy są funktorami nad jakimś typem. Oznacza to, że biorąc pod uwagę algebrę nad typem „a”, można wygenerować zgodną algebrę list zawierających elementy typu „a”. (Na przykład: mapa, która przenosi element do listy singletonów zawierającej go: f (a) = [a]) Ponownie pojęcie zgodności wyraża się w prawach funktora.
Z drugiej strony, biorąc pod uwagę funktor f „nad” typem a (to znaczy fa jest wynikiem zastosowania funktora f do algebry typu a) i funkcji z g: a -> b, możemy obliczyć nowy funktor F = (fmap g), który odwzorowuje fa na f b. Krótko mówiąc, fmap jest częścią F, która mapuje „części funktora” na „części funktora”, a g jest częścią funkcji, która mapuje „części algebry” na „części algebry”. Pobiera funkcję, funktor, a po zakończeniu JEST funktorem.
Może się wydawać, że różne języki używają różnych pojęć funktorów, ale tak nie jest. Używają po prostu funktorów w różnych algebrach. OCamls ma algebrę modułów, a funktory tej algebry pozwalają dołączać nowe deklaracje do modułu w „zgodny” sposób.
Funktor Haskell NIE jest klasą typu. Jest to typ danych z dowolną zmienną, która spełnia klasę typu. Jeśli chcesz zagłębić się w wnętrzności typu danych (bez wolnych zmiennych), możesz ponownie zinterpretować typ danych jako funktor nad podstawową algebrą. Na przykład:
dane F = F Int
jest izomorficzny do klasy Ints. Zatem F, jako konstruktor wartości, jest funkcją odwzorowującą Int na F Int, równoważną algebrę. To jest funktor. Z drugiej strony nie dostajesz tutaj fmap za darmo. Do tego właśnie służy dopasowanie wzorca.
Functory są dobre do „przyczepiania” rzeczy do elementów algebry w sposób algebraicznie zgodny.
źródło
Najlepsza odpowiedź na to pytanie znajduje się w „Typeclassopedia” Brenta Yorgeya.
To wydanie Monad Reader zawiera dokładną definicję tego, czym jest funktor, a także wiele innych definicji, a także schemat. (Pojęcie monoidalne, aplikacyjne, monadowe i inne są wyjaśnione i postrzegane w odniesieniu do funktora).
http://haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf
fragment Typeclassopedia for Functor: „Prostą intuicją jest to, że Functor reprezentuje pewnego rodzaju„ pojemnik ”, wraz z możliwością równomiernego zastosowania funkcji do każdego elementu w pojemniku”
Ale tak naprawdę cała ta typeclassopedia jest wysoce zalecaną lekturą, która jest zaskakująco łatwa. W taki sposób można zobaczyć prezentowaną tam typkę jako wzór równoległy do wzorca projektowego w obiekcie, w tym sensie, że dają ci słownictwo dotyczące danego zachowania lub możliwości.
Twoje zdrowie
źródło
Jest całkiem dobry przykład w książce O'Reilly OCaml, która znajduje się na stronie internetowej Inrii (która w chwili pisania tego niestety nie działa). Znalazłem bardzo podobny przykład w tej książce używanej przez caltech: Wprowadzenie do OCaml (link pdf) . Odpowiednią sekcją jest rozdział dotyczący funktorów (strona 139 w książce, strona 149 w pliku PDF).
W książce mają funktor o nazwie MakeSet, który tworzy strukturę danych, która składa się z listy, i funkcje dodawania elementu, określania, czy element znajduje się na liście i znajdowania elementu. Sparametryzowano funkcję porównawczą, która służy do określenia, czy jest w zestawie, czy nie. (Co czyni MakeSet funktorem zamiast modułu).
Mają także moduł, który implementuje funkcję porównania, dzięki czemu porównuje ciąg znaków bez rozróżniania wielkości liter.
Za pomocą funktora i modułu, który implementuje porównanie, mogą utworzyć nowy moduł w jednym wierszu:
który tworzy moduł dla ustalonej struktury danych, która wykorzystuje porównania bez rozróżniania wielkości liter. Jeśli chcesz utworzyć zestaw, w którym używane są rozróżnienia wielkości liter, wystarczy zaimplementować nowy moduł porównania zamiast nowego modułu struktury danych.
Tobu porównał funktory do szablonów w C ++, które moim zdaniem są całkiem trafne.
źródło
Biorąc pod uwagę inne odpowiedzi i to, co zamierzam teraz opublikować, powiedziałbym, że to dość mocno przeciążone słowo, ale w każdym razie ...
Aby uzyskać podpowiedź dotyczącą znaczenia słowa „funktor” w języku Haskell, zapytaj GHCi:
Zasadniczo funktor w Haskell jest czymś, co można zmapować. Innym sposobem na powiedzenie jest to, że funktor to coś, co można uznać za kontener, o który można poprosić o użycie danej funkcji do przekształcenia zawartej w niej wartości; Zatem, na listach,
fmap
zbiega się zmap
, naMaybe
,fmap f (Just x) = Just (f x)
,fmap f Nothing = Nothing
itd.Podsekcja typu Functor oraz sekcja Functors, Functors Applicative i Monoids of Learn You a Haskell for Great Good podają przykłady przydatności tej konkretnej koncepcji. (Podsumowanie: wiele miejsc! :-))
Zauważ, że każdą monadę można traktować jako funktor, a tak naprawdę, jak zauważa Craig Stuntz, najczęściej używanymi funktorami są zwykle monady ... OTOH, wygodnie jest czasami zrobić typ instancji klasy Functor bez kłopotów z robieniem z niego Monady. (Np. W przypadku
ZipList
zControl.Applicative
, wymienionego na jednej z wyżej wymienionych stron .)źródło
Oto artykuł na temat funktorów z POV programowania , a następnie dokładniej, jak ukazują się one w językach programowania .
Praktyczne użycie funktora jest w monadzie, a jeśli o to chodzi, możesz znaleźć wiele samouczków na temat monad.
źródło
W komentarzu do najczęściej głosowanej odpowiedzi użytkownik Wei Hu pyta:
Uwaga : nie znam ML, więc proszę wybacz i popraw wszelkie powiązane błędy.
Załóżmy początkowo, że wszyscy znamy definicje „kategorii” i „funktora”.
Krótka odpowiedź brzmiałaby, że „funktory Haskella” są funktorami (endo-),
F : Hask -> Hask
podczas gdy „funktory ML” są funktoramiG : ML -> ML'
.Tutaj
Hask
jest kategoria utworzona przez typy Haskell i funkcje między nimi, i podobnieML
iML'
są kategoriami zdefiniowanymi przez struktury ML.Uwaga : istnieją pewne problemy techniczne z tworzeniem
Hask
kategorii, ale istnieją sposoby ich obejścia.Z teoretycznego punktu widzenia kategorii oznacza to, że
Hask
funkcja jest mapąF
typów Haskella:wraz z mapą
fmap
funkcji Haskell:ML jest prawie taki sam, chociaż nie
fmap
znam kanonicznej abstrakcji, więc zdefiniujmy jedną:To znaczy
f
mapy -ML
typy ifmap
mapy -ML
funkcje, więcjest funktorem
F: StructA -> StructB
.źródło
„Functor to mapowanie obiektów i morfizmów, które zachowuje kompozycję i tożsamość kategorii”.
Zdefiniujmy, co to jest kategoria?
Co obejmuje kategoria?
Musimy więc zmapować obiekty i zachować kompozycję po zastosowaniu naszego Functora.
Wyobraźmy sobie, że „A” to nasza kategoria, która ma obiekty [„a”, „b”] i istnieje morfizm a -> b
Teraz musimy zdefiniować funktor, który może zmapować te obiekty i morfizmy do innej kategorii „B”.
Powiedzmy, że funktor nazywa się „Może”
Tak więc kategoria „B” wygląda następująco.
Narysuj kolejne koło, ale tym razem za pomocą „Może a” i „Może b” zamiast „a” i „b”.
Wszystko wydaje się dobre, a wszystkie obiekty są mapowane
„a” stało się „Może a”, a „b” stało się „Być może b”.
Problem polega jednak na tym, że musimy zmapować morfizm również z „a” na „b”.
Oznacza to, że morfizm a -> b w „A” powinien odwzorowywać na morfizm „Może a” -> „Może b”
morfizm z a -> b nazywa się f, następnie morfizm z „Może a” -> „Może b” nazywa się „fmap f”
Zobaczmy teraz, jaką funkcję „f” pełniła w „A” i zobaczmy, czy możemy ją replikować w „B”
definicja funkcji „f” w „A”:
f bierze a i zwraca b
definicja funkcji „f” w „B”:
f bierze Może a i zwraca Może b
zobaczmy, jak używać fmap do mapowania funkcji „f” z „A” na funkcję „fmap f” w „B”
definicja fmap
Co my tu robimy?
Stosujemy funkcję „f” do „x”, który jest typu „a”. Specjalne dopasowanie wzorca „Nic” pochodzi z definicji
Functor Maybe
.Tak więc zamapowaliśmy nasze obiekty [a, b] i morfizmy [f] z kategorii „A” na kategorię „B”.
To jest Functor!
źródło
Szorstki przegląd
W programowaniu funkcjonalnym funktor jest zasadniczo konstrukcją podnoszenia zwykłych funkcji jednoargumentowych (tj. Tych z jednym argumentem) do funkcji między zmiennymi nowych typów. Znacznie łatwiej jest pisać i utrzymywać proste funkcje między prostymi obiektami i używać funktorów do ich podnoszenia, a następnie ręcznie pisać funkcje między skomplikowanymi obiektami kontenerowymi. Kolejną zaletą jest napisanie prostych funkcji tylko raz, a następnie ponowne użycie ich za pomocą różnych funktorów.
Przykłady funktorów obejmują tablice, funty „może” i „albo”, futures (patrz np. Https://github.com/Avaq/Fluture ) i wiele innych.
Ilustracja
Rozważ funkcję konstruującą pełne imię i nazwisko osoby na podstawie imienia i nazwiska. Możemy to zdefiniować
fullName(firstName, lastName)
jako funkcję dwóch argumentów, co jednak nie byłoby odpowiednie dla funktorów, które zajmują się funkcjami tylko jednego argumentu. Aby temu zaradzić, zbieramy wszystkie argumenty w jednym obiekciename
, który teraz staje się pojedynczym argumentem funkcji:Co teraz, jeśli mamy wiele osób w jednym szeregu? Zamiast ręcznie przeglądać listę, możemy po prostu ponownie użyć naszej funkcji
fullName
za pomocąmap
metody przewidzianej dla tablic z krótkim pojedynczym wierszem kodu:i używaj go jak
Będzie to działać, ilekroć każdy wpis w naszym
nameList
obiekcie jest obiektem zapewniającym zarówno właściwości, jakfirstName
ilastName
właściwości. Ale co, jeśli niektóre obiekty nie (a nawet wcale nie są)? Aby uniknąć błędów i uczynić kod bezpieczniejszym, możemy owinąć nasze obiekty wMaybe
typ (patrz np. Https://sanctuary.js.org/#maybe-type ):gdzie
Just(name)
jest pojemnikiem zawierającym tylko prawidłowe nazwy iNothing()
jest specjalną wartością używaną do wszystkiego innego. Teraz zamiast przerywać (lub zapominać) sprawdzanie poprawności naszych argumentów, możemy po prostu ponownie użyć (podnieść) naszą oryginalnąfullName
funkcję z innym pojedynczym wierszem kodu, ponownie opartym namap
metodzie, tym razem przewidzianym dla typu Może:i używaj go jak
Teoria kategorii
Funktora w teorii kategorii znajduje się mapa dwie kategorie poszanowaniem skład swoich morfizmów. W języku komputerowym główną kategorią zainteresowań jest ta, której obiektami są typy (określone zestawy wartości) i której morfizmy są funkcjami
f:a->b
jednego typua
na innyb
.Na przykład, weźmy
a
się zaString
typ,b
Liczba if
jest funkcją odwzorowującą ciąg znaków na jego długość:Tutaj
a = String
reprezentuje zestaw wszystkich ciągów ib = Number
zestaw wszystkich liczb. W tym sensie, jaka
ib
reprezentacji obiektów w Set Kategorii (co jest ściśle związane z kategorią typów, z tą różnicą, nieistotne tutaj). W kategorii zestawu morfizmy między dwoma zestawami są dokładnie wszystkimi funkcjami od pierwszego zestawu do drugiego. Zatem naszą funkcją długościf
jest morfizm ze zbioru ciągów na zbiór liczb.Ponieważ bierzemy pod uwagę tylko zestaw kategorii, odpowiedni funktorami z niej samych są mapy wysyłające obiekty do obiektów i morfizmy do morfizmów, które spełniają pewne prawa algebraiczne.
Przykład:
Array
Array
może oznaczać wiele rzeczy, ale tylko jedna rzecz to Functor - konstrukcja typu, mapująca typa
na typ[a]
wszystkich tablic typua
. Na przykładArray
funktor odwzorowuje typString
na typ[String]
(zbiór wszystkich tablic ciągów o dowolnej długości), a zestaw typNumber
na odpowiedni typ[Number]
(zbiór wszystkich tablic liczb).Ważne jest, aby nie mylić mapy Functor
z morfizmem
a -> [a]
. Funktor po prostu odwzorowuje (kojarzy) typa
na typ[a]
jako jedna rzecz na drugą. To, że każdy typ jest w rzeczywistości zestawem elementów, nie ma tutaj znaczenia. Natomiast morfizm jest faktyczną funkcją między tymi zbiorami. Na przykład występuje naturalny morfizm (funkcja)który wysyła wartość do tablicy 1-elementowej z tą wartością jako pojedynczy wpis. Ta funkcja nie jest częścią
Array
Functora! Z punktu widzenia tego funktorapure
jest to jak każda inna funkcja, nic specjalnego.Z drugiej strony
Array
Functor ma swoją drugą część - część morfizmu. Któryf :: a -> b
zamienia morfizm w morfizm[f] :: [a] -> [b]
:Oto
arr
dowolna tablica o dowolnej długości z wartościami typua
iarr.map(f)
jest tablicą o tej samej długości z wartościami typub
, których wpisy są wynikiem zastosowaniaf
do wpisów zarr
. Aby uczynić go funktorem, muszą obowiązywać matematyczne prawa odwzorowywania tożsamości na tożsamość i kompozycji na kompozycje, które łatwo sprawdzić w tymArray
przykładzie.źródło
Aby nie zaprzeczyć poprzednim teoretycznym lub matematycznym odpowiedziom, ale Functor to także Obiekt (w języku programowania obiektowego), który ma tylko jedną metodę i jest skutecznie wykorzystywany jako funkcja.
Przykładem jest interfejs Runnable w Javie, który ma tylko jedną metodę: uruchom.
Rozważ ten przykład, najpierw w JavaScript, który ma pierwszorzędne funkcje:
Wyjście: [1, 4, 25, 100]
Metoda map przyjmuje funkcję i zwraca nową tablicę, przy czym każdy element jest wynikiem zastosowania tej funkcji do wartości w tej samej pozycji w oryginalnej tablicy.
Aby zrobić to samo, co Java, używając Functora, najpierw musisz zdefiniować interfejs, powiedz:
Następnie, jeśli dodasz klasę kolekcji, która miała funkcję mapy, możesz:
Wykorzystuje on wbudowaną podklasę IntMapFunction, aby utworzyć Functor, który jest odpowiednikiem OO funkcji z wcześniejszego przykładu JavaScript.
Korzystanie z Functors pozwala stosować techniki funkcjonalne w języku OO. Oczywiście niektóre języki OO również obsługują funkcje bezpośrednio, więc nie jest to wymagane.
Odniesienie: http://en.wikipedia.org/wiki/Function_object
źródło
Array
Jest funktorem, aleArray(value)
daje tylko tablice 1-elementowe.KISS: Funktor to obiekt posiadający metodę mapy.
Tablice w JavaScript implementują mapę i dlatego są funktorami. Obietnice, strumienie i drzewa często implementują mapę w językach funkcjonalnych, a kiedy to robią, są uważane za funktory. Metoda mapy funktora pobiera własną zawartość i przekształca każdą z nich za pomocą wywołania zwrotnego transformacji przekazanego do mapy, i zwraca nowy funktor, który zawiera strukturę jako pierwszy funktor, ale z przekształconymi wartościami.
src: https://www.youtube.com/watch?v=DisD9ftUyCk&feature=youtu.be&t=76
źródło
Array
Konstrukcja typu definiuje pojedynczy funktor. Jego instancje są również nazywane „tablicami”, ale nie są funktorami. Opis tutaj powinien być bardziej precyzyjny.W praktyce funktor oznacza obiekt, który implementuje operator wywołania w C ++. W ocaml myślę, że funktor odnosi się do czegoś, co przyjmuje moduł jako dane wejściowe i wyjściowe innego modułu.
źródło
Mówiąc prościej, funktor lub obiekt funkcji jest obiektem klasy, który można wywołać tak jak funkcję.
W C ++:
Tak piszesz funkcję
Tak piszesz funktor
Teraz możesz to zrobić:
To, co sprawia, że są tak świetne, to to, że możesz zachować stan w klasie - wyobraź sobie, że chcesz zapytać funkcję, ile razy została wywołana. Nie da się tego zrobić w zgrabny, zamknięty sposób. Z obiektem funkcyjnym jest jak każda inna klasa: miałbyś jakąś zmienną instancji, którą zwiększasz,
operator ()
i jakąś metodę sprawdzania tej zmiennej, i wszystko jest w porządku, jak chcesz.źródło
FunctorClass
spełnia on pierwsze Prawo Funktora, ale czy mógłbyś naszkicować dowód na drugie Prawo? Nie do końca to widzę.Functor nie jest ściśle związany z programowaniem funkcjonalnym. To tylko „wskaźnik” do funkcji lub jakiegoś obiektu, który można wywołać tak, jakby był funkcją.
źródło