Funktory v C++

CxxDaemon

Funktory v C++
« kdy: 09. 05. 2017, 12:12:37 »
V knize o metaprogramování v C++ píšou, že něco jako "template<typename T> class C" je "funktor", ovšem bez nějakého bližšího kontextu. Může mi někdo polopatisticky vysvětlit, co to je funktor a jak to je relevantní pro C++?


hu

Re:Funktory v C++
« Odpověď #1 kdy: 09. 05. 2017, 12:30:50 »
V knize o metaprogramování v C++ píšou, že něco jako "template<typename T> class C" je "funktor", ovšem bez nějakého bližšího kontextu. Může mi někdo polopatisticky vysvětlit, co to je funktor a jak to je relevantní pro C++?

https://en.wikipedia.org/wiki/Function_object

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Funktory v C++
« Odpověď #2 kdy: 09. 05. 2017, 12:47:33 »
V knize o metaprogramování v C++ píšou, že něco jako "template<typename T> class C" je "funktor", ovšem bez nějakého bližšího kontextu. Může mi někdo polopatisticky vysvětlit, co to je funktor a jak to je relevantní pro C++?

https://en.wikipedia.org/wiki/Function_object
Chyba, to je něco úplně jiného. Je propastný rozdíl mezi volatelným objektem (std::function) a funktorem v kategorii typů nějakého jazyka (zdejší případ v kontextu generického programování).

lopata

Re:Funktory v C++
« Odpověď #3 kdy: 09. 05. 2017, 12:54:57 »
Chyba, to je něco úplně jiného. Je propastný rozdíl mezi volatelným objektem (std::function) a funktorem v kategorii typů nějakého jazyka (zdejší případ v kontextu generického programování).

Bohužel sis nepřečetl zadání: Může mi někdo polopatisticky vysvětlit... Takže je tvoje odpověd zcela nerelevantní.

xavi



expert

Re:Funktory v C++
« Odpověď #5 kdy: 09. 05. 2017, 13:14:01 »
Kód: [Vybrat]
template<typename T> class C; /*< forward deklarace - neni funktor */

template<typename T> class C
{
public:
   /* definice funkce, stale se nejedna o funktor */
   void operator()
   {
      std::cout << "I'm functor" << std::endl;
   }   
};

C<int> c;  /*< c je functor */

c(); /* I'm functor */


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Funktory v C++
« Odpověď #6 kdy: 09. 05. 2017, 13:15:05 »

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Funktory v C++
« Odpověď #7 kdy: 09. 05. 2017, 13:22:15 »
V knize o metaprogramování v C++ píšou, že něco jako "template<typename T> class C" je "funktor", ovšem bez nějakého bližšího kontextu. Může mi někdo polopatisticky vysvětlit, co to je funktor a jak to je relevantní pro C++?
Tyto "funktory" jsou v každém jazyce s generickými typy, až na to, že to nejsou funktory (podle definice), protože nefungují na morfismech, takže čistě formálně je to funkční restrikce funktoru pomíjející morfismy. A polopatě: "a functor is a function taking objects of a category to objects of another category". V jazycích jako C++, Java, Swift, Go apod. jde o kategorii typů. Čili třeba z int udělám C<int>, kde C je ten "funktor" přiřazující typu int onen složitější typ. Toť vše. S operátorem () to nijak nesouvisí, v Javě to je úplně stejné.

hu

Re:Funktory v C++
« Odpověď #8 kdy: 09. 05. 2017, 13:23:30 »
V knize o metaprogramování v C++ píšou, že něco jako "template<typename T> class C" je "funktor", ovšem bez nějakého bližšího kontextu. Může mi někdo polopatisticky vysvětlit, co to je funktor a jak to je relevantní pro C++?

https://en.wikipedia.org/wiki/Function_object
Chyba, to je něco úplně jiného. Je propastný rozdíl mezi volatelným objektem (std::function) a funktorem v kategorii typů nějakého jazyka (zdejší případ v kontextu generického programování).

Máš samozřejme pravdu, moje culpa.

JSH

Re:Funktory v C++
« Odpověď #9 kdy: 09. 05. 2017, 13:26:16 »
Pro lidi :

V C++ světě je funktor objekt s operátorem závorky, takže jde zavolat jako funkce.

V Haskell světě (i jinde, je to z teorie kategorií) je to "funkce" nad typy. vector<> je "funkce", která bere typ prvku a vrací specializovaný kontejner.

lopata

Re:Funktory v C++
« Odpověď #10 kdy: 09. 05. 2017, 13:32:53 »
Pro lidi :

V C++ světě je funktor objekt s operátorem závorky, takže jde zavolat jako funkce.

V Haskell světě (i jinde, je to z teorie kategorií) je to "funkce" nad typy. vector<> je "funkce", která bere typ prvku a vrací specializovaný kontejner.

Přesně tak, v C++ se bežně termín funktor (zne)užívá pro funkční objekt. Můžeme s tím nesouhlasit, můžeme proti tomu protestovat, ale to je to jediné, co s tím můžeme dělat.

Pokud se chce někdo vrtat ve formálních rozdílech, teorii kategorí, monádách apod., tak zde: http://jackieokay.com/2017/01/26/functors.html

andy

Re:Funktory v C++
« Odpověď #11 kdy: 09. 05. 2017, 14:04:18 »
Tak jsem myslel, že na to někdo odpoví "po lopatě" (to je totiž hezky česky)....

Po lopatě, funktor je kontejner, který má operaci pro práci s prvky, co jsou uvnitř, která splňuje nějaké základní náležitosti (aby se to dalo považovat za kontejner).

"template<typename T> class C" je schopné být funktor, protože ta funkce, která dělá něco s tím, co je uvnitř, může taky měnit ten typ.

Ta operace se jmenuje "fmap", vypadá jako "C<T2> fmap(f, C<T1>)" a "f" je "T2 f(T1)". Typická implementace je, že to pro každý prvek toho kontejneru zavolá tu funkci "f", prvek vymění za nový a vrátí výsledek (může se změnit typ). A aby to splňovalo tu představu "kontejneru", tak to musí splňovat, že
Kód: [Vybrat]
id(x) { return x; }
fmap(id, container) == container

sloz(x) { return p(q(x)) }
fmap(sloz, container) == fmap(p, fmap(q))
(C++ syntaxi pořádně neumim, tak je to trochu pseudo)

Třeba takový generický "seznam" je funktor - operace fmap se zavolá pro každý prvek a vrátí se výsledek. Optional je funktor - když v něm nic není, vrátí nic, jinak zavolá tu funkci a vrátí nový optional s jiným výsledkem. Hashmapa je funktor - fmap se volá na hodnoty. Funkce je funktor; fmap se zavolá na výsledek funkce (vlastně složení funkcí).

Jinak tady to je i s tou teorií i C++ příklady:
https://bartoszmilewski.com/2015/01/20/functors/

Re:Funktory v C++
« Odpověď #12 kdy: 09. 05. 2017, 14:05:12 »
Bohužel sis nepřečetl zadání: Může mi někdo polopatisticky vysvětlit...
Pokud někdo chcete polopatistické vysvětlení toho "skutečného" funktoru, tak tohle je docela dobrý: http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

Re:Funktory v C++
« Odpověď #13 kdy: 09. 05. 2017, 14:18:10 »
Po lopatě, funktor je kontejner, který má operaci pro práci s prvky
To je sice pěkně po lopatě, ale je to zavádějící. I funkce může být functor...

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Funktory v C++
« Odpověď #14 kdy: 09. 05. 2017, 14:18:44 »
Tak jsem myslel, že na to někdo odpoví "po lopatě" (to je totiž hezky česky)....

Po lopatě, funktor je kontejner, který má operaci pro práci s prvky, co jsou uvnitř, která splňuje nějaké základní náležitosti (aby se to dalo považovat za kontejner).

"template<typename T> class C" je schopné být funktor, protože ta funkce, která dělá něco s tím, co je uvnitř, může taky měnit ten typ.

Ta operace se jmenuje "fmap", vypadá jako "C<T2> fmap(f, C<T1>)" a "f" je "T2 f(T1)". Typická implementace je, že to pro každý prvek toho kontejneru zavolá tu funkci "f", prvek vymění za nový a vrátí výsledek (může se změnit typ). A aby to splňovalo tu představu "kontejneru", tak to musí splňovat, že
Kód: [Vybrat]
id(x) { return x; }
fmap(id, container) == container

sloz(x) { return p(q(x)) }
fmap(sloz, container) == fmap(p, fmap(q))
(C++ syntaxi pořádně neumim, tak je to trochu pseudo)

Třeba takový generický "seznam" je funktor - operace fmap se zavolá pro každý prvek a vrátí se výsledek. Optional je funktor - když v něm nic není, vrátí nic, jinak zavolá tu funkci a vrátí nový optional s jiným výsledkem. Hashmapa je funktor - fmap se volá na hodnoty. Funkce je funktor; fmap se zavolá na výsledek funkce (vlastně složení funkcí).

Jinak tady to je i s tou teorií i C++ příklady:
https://bartoszmilewski.com/2015/01/20/functors/
Akorát to nemusí být kontejner.