Vytvořit lambdu která volá Cčkovskou funkci není čisté, a rozhodně o nic víc než zavolání té funkce rovnou. A runtimu se nic nepředává, runtime Haskellu nemá žádný modul pro IO. A i kdyby se předávalo, na faktu že v čistém jazyce píšeme kód s vedlejšími efekty se nic nezmění.
Ještě jednou: ve funkci main jenom vytvoříš datovou strukturu, která popisuje nějaký sled akcí. Pokud generování datové struktury "není čisté", tak už fakt nevím, co by mělo být čisté...
Čistotu IO monády jsem začal zpochybňovat od té doby, co jsem ji začal používat i k něčemu složitějšímu než čtení a zapisování do konzole. Ačkoli, já jsem ji nezačal zpochybňovat, já jsem se snažil zoufale pochopit jak to může být funkcionální. Řešení je prosté, není. A rozepsání nic nemění. Po rozepsání to sice nebude vypadat jak kód v Cčku, ale chovat se bude stejně.
Ale jistěže to je funkcionální, v tom nejstriktnějším možném slova smyslu. Pokud tomu nevěříš, tak si to asi budeš muset nastudovat do hloubky včetně teorie kategorií, kde to uvidíš jasně a důkaz tam budeš mít rigorozní.
Pokud máš pocit, že "to funkcionální není", tak ty důvody rozepiš formálně: podej definici "funkcionální" a ukaž, který z bodů to podle tebe nesplňuje. Skoro bych řekl, že by ti mělo být předem jasné, že nemáš šanci uspět, protože za touhle celou strukturou jsou mozky, které fakt nedělají nějaké hloupé chyby...
Ano, vytvoří se neměnná datová struktura, v které jsou lambdy s vedlejšími efekty. A když se tato struktura poté vyhodnocuje, začnou se vedlejší efekty projevovat. Mám dvě otázky. Pokud je IO monáda čistá, lze udělat následující strukturu kódu
-----------------------------------------------
IO
-----------------------------------------------
Bez IO monády
-----------------------------------------------
IO
-----------------------------------------------
ale v Haskellu to nejde. Neexisuje něco jako runIO protože runIO nelze nahradit svým výstupem. A druhá otázka, pokud je IO monáda čistá, proč ji nemůžeme zparalelizovat pomocí par? Neměl by to být problém ne? Ale v Haskellu to nejde. Par ignoruje IO monádu.
Třeba u STRef je možnost zavolat runST, a tím umístit ST monádu i do čistého kódu, ST monáda je ale navenek čistá, neumožňuje vedlejší efekty, takže výstup je deterministický ačkoli ve vnitřku ST monáda čistá není.