5. jsem zkoušel, ale teď teprve vím, že "data" je jen funkce a začíná mi to dávat logiku.
"data" samo o sobě je klíčové slovo, ne funkce. To, o co jde, je, že data contructor je vlastně funkce. Když mám třeba
Prelude> data MujParadniTyp = PismenkovaHodnota String | CiselnaHodnota Int
tak máme vlastně dvě funkce, které mi ze Stringu nebo Intu vytvoří MujParadniTyp
Prelude> :t PismenkovaHodnota
PismenkovaHodnota :: String -> MujParadniTyp
Prelude> :t CiselnaHodnota
CiselnaHodnota :: Int -> MujParadniTyp
- v podstatě tu hodnotu zavřou do krabice. Krabice může obsahovat String nebo Int hodnotu a krabice samotná má typ MujParadniTyp. V pythonu by se pro podobnej efekt použil tuple:
("PismenkovaHodnota","hola hola")
("CiselnaHodnota",1)
by odpovídalo Haskellovskému
(PismenkovaHodnota "hola hola")
(CiselnaHodnota 1)
- v Haskellu se krabice prostě dá udělat funkcí a můžu pak dělat pattern matching, to by ve většině jazyků nešlo - funkce je pro ně něco, co jde jenom spustit. Pro Haskell ne

A tohodle "zavírání do krabic" se právě chytře používá mj. v těch monádách. A protože krabice i její obsah je vždycky haskellovský typ, tak ta funkce CiselnaHodnota je ze stejné kategorie do stejné kategorie a je to ... tramtadadá! ... ten slavný endofunktor!

(EDIT: teda respektive byl by, pokud by byl nadefinovaný pro libovolný typ, ne jenom pro String)