Map vs. FlatMap

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Map vs. FlatMap
« Odpověď #90 kdy: 28. 09. 2016, 12:09:52 »
flatMap má typ ma->(a->ma)->ma. Kde přesně je ten rozpor?
já si představuju typ t a -> (a -> m b) -> m b, jednak jste mluvil o monádě na výstupu, což IMHO znamená, že na vstupu je něco jiného, druhak Data.Foldable.foldMap (se jeví takový pohodlnější) a za třetí ten váš flatMap je dost omezený co se týče mapování samotného (a -> a), ale to je asi překlep
Ten typ, co jsem napsal, je *definice* flatMap. Join, unit a flatMap jsou přesně definované a navzájem provázané a není možné jejich typy měnit. Samozřejmě se dá vymyslet nějaká jiná užitečná funkce nad monádami, ale pak by se neměla jmenovat flatMap, protože to je pevně daný koncept, stejně jako si nemůžu říct, že "celé číslo" pro mě od teď budou všechna racionální čísla větší než π (teda říct si to můžu, ale pak se s nikým nedomluvím).


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Map vs. FlatMap
« Odpověď #91 kdy: 28. 09. 2016, 12:13:15 »
@v Sorry ale nerozumím. Můžeš prosím znovu co nejsrozumitelněji naformulovat celou otázku v jednom příspěvku bez odkazů na předchozí příspěvky, ať se vyhrabeme z toho zmatku? Díky..
to nevím jestli umím :D

IMHO vrcholu srozumitelnosti jsem dosáhl, když jsem se zeptal jestli je možné implementovat tuto funkci:
f :: Monad m => m a  -> m a -> m a
tak aby f [1] [2] == [1,2]
motivace pro tento dotaz je příspěvěk zboj  27. 09. 2016, 15:24:02
(implementace f a b = join [a, b] neodpovídá zadanému datovému typu)

Hmm, řekl bych že to nejde. U listu to vypadá v pohodě, ale jak by vůbec měl vypadat očekávaný výsledek třeba na Maybe?

f (Just 1) (Just 2) = ??

Pravda, není to moc rigorózní úvaha, ale intuitivně se mi zdá, že f tak jak ho chceš naimplementovat nejde.
Aby to dávalo smysl, monáda musí být aditivní, pak stačí funkci definovat jako x++y. Tím jsme ale dost odbočili od flatMap.

Nojo, tak to je ale trochu podvod :) Ale interpretuju to tak, že na Monad f implementovat nejde, na MonadPlus jo.
Jistě, bez nějaké dodatečné struktury konkatenace smysluplně definovat nejde. Taky jsem nikdy netvrdil, že něco takového je možné a popravdě moc ani smysl té původní otázky nechápu. Vzhledem k nedávnému vývoji této diskuze asi nedorozumění způsobil zmatek ohledně typu flatMap (viz výše).

v

Re:Map vs. FlatMap
« Odpověď #92 kdy: 28. 09. 2016, 12:22:00 »
flatMap má typ ma->(a->ma)->ma. Kde přesně je ten rozpor?
já si představuju typ t a -> (a -> m b) -> m b, jednak jste mluvil o monádě na výstupu, což IMHO znamená, že na vstupu je něco jiného, druhak Data.Foldable.foldMap (se jeví takový pohodlnější) a za třetí ten váš flatMap je dost omezený co se týče mapování samotného (a -> a), ale to je asi překlep
Ten typ, co jsem napsal, je *definice* flatMap. Join, unit a flatMap jsou přesně definované a navzájem provázané a není možné jejich typy měnit. Samozřejmě se dá vymyslet nějaká jiná užitečná funkce nad monádami, ale pak by se neměla jmenovat flatMap, protože to je pevně daný koncept, stejně jako si nemůžu říct, že "celé číslo" pro mě od teď budou všechna racionální čísla větší než π (teda říct si to můžu, ale pak se s nikým nedomluvím).
pak tedy je problém čistě ve formulaci "na výstupu"

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Map vs. FlatMap
« Odpověď #93 kdy: 28. 09. 2016, 14:07:58 »
flatMap má typ ma->(a->ma)->ma. Kde přesně je ten rozpor?
já si představuju typ t a -> (a -> m b) -> m b, jednak jste mluvil o monádě na výstupu, což IMHO znamená, že na vstupu je něco jiného, druhak Data.Foldable.foldMap (se jeví takový pohodlnější) a za třetí ten váš flatMap je dost omezený co se týče mapování samotného (a -> a), ale to je asi překlep
Ten typ, co jsem napsal, je *definice* flatMap. Join, unit a flatMap jsou přesně definované a navzájem provázané a není možné jejich typy měnit. Samozřejmě se dá vymyslet nějaká jiná užitečná funkce nad monádami, ale pak by se neměla jmenovat flatMap, protože to je pevně daný koncept, stejně jako si nemůžu říct, že "celé číslo" pro mě od teď budou všechna racionální čísla větší než π (teda říct si to můžu, ale pak se s nikým nedomluvím).
pak tedy je problém čistě ve formulaci "na výstupu"
Výstupním typem je libovolná, ale stejná monáda (např. List, Future nebo Continuation), základový typ může být jiný (jakýkoliv).

Re:Map vs. FlatMap
« Odpověď #94 kdy: 28. 09. 2016, 14:15:01 »
to se mi nějak nezdá, jak se pomocí monadického rozhraní poskládá (např.) seznam?

Pokud jsem pochopil otazku, tak by mohlo vysvetlit tohle:
https://en.wikibooks.org/wiki/Haskell/Understanding_monads/List
možná tam je, ale já ji nevidim, možná jsem se v tom trošku ztratil
otázka by mohla být jak pomocí (>>=) a return (když už teda chcete haskell) udělám z [1] a [2] hodnotu [1,2]
Myslím, že zboj myslel spíš to, že pomocí bindu můžu hezky "simulovat" map i flatMap:

map:
Kód: [Vybrat]
Prelude> [1,2,3] >>= (\x -> [x*2])
[2,4,6]

flatMap:
Kód: [Vybrat]
Prelude> [1,2,3] >>= (\x -> [x,x])
[1,1,2,2,3,3]

filter:
Kód: [Vybrat]
Prelude> [1,2,3] >>= (\x -> if x==1 then [] else [x])
[2,3]

...ale ne naopak, čili bind je "silnější"/"obecnější" koncept.

Samozřejmě to neznamená, že by si nějaká obecná fce nad monádami vycucala z prstu, že když dostane dva listy, tak je má zřetězit, to jí samozřejmě musím nějak říct, že má udělat zrovna toto :)
« Poslední změna: 28. 09. 2016, 14:17:38 od Mirek Prýmek »


Re:Map vs. FlatMap
« Odpověď #95 kdy: 28. 09. 2016, 14:30:54 »
Samozřejmě to neznamená, že by si nějaká obecná fce nad monádami vycucala z prstu, že když dostane dva listy, tak je má zřetězit, to jí samozřejmě musím nějak říct, že má udělat zrovna toto :)
Ještě dodatek k tomuhle: myslím, že není od věci si uvědomit, že "být monádou" je jenom zkratka pro to, že mám nějaký substrát a nad ním nějaké operace, které splňují nějaká pravidla. Je dost pravděpodobný (teď z hlavy si nevybavím příklad a nechce se mi to řešit), že List může být monádou "různými způsoby" - ty operace si nadefinuju různě, ale ve všech případech jsou splněny "monadické zákony". Ne ve všech těhle různých případech musí figurovat zřetězení.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Map vs. FlatMap
« Odpověď #96 kdy: 28. 09. 2016, 14:48:00 »
to se mi nějak nezdá, jak se pomocí monadického rozhraní poskládá (např.) seznam?

Pokud jsem pochopil otazku, tak by mohlo vysvetlit tohle:
https://en.wikibooks.org/wiki/Haskell/Understanding_monads/List
možná tam je, ale já ji nevidim, možná jsem se v tom trošku ztratil
otázka by mohla být jak pomocí (>>=) a return (když už teda chcete haskell) udělám z [1] a [2] hodnotu [1,2]
Myslím, že zboj myslel spíš to, že pomocí bindu můžu hezky "simulovat" map i flatMap:

map:
Kód: [Vybrat]
Prelude> [1,2,3] >>= (\x -> [x*2])
[2,4,6]

flatMap:
Kód: [Vybrat]
Prelude> [1,2,3] >>= (\x -> [x,x])
[1,1,2,2,3,3]

filter:
Kód: [Vybrat]
Prelude> [1,2,3] >>= (\x -> if x==1 then [] else [x])
[2,3]

...ale ne naopak, čili bind je "silnější"/"obecnější" koncept.

Samozřejmě to neznamená, že by si nějaká obecná fce nad monádami vycucala z prstu, že když dostane dva listy, tak je má zřetězit, to jí samozřejmě musím nějak říct, že má udělat zrovna toto :)
Ne tak úplně, bind je flatMap, jsou to jen různá pojmenování stejné operace (stejně jako join a flatten).

Re:Map vs. FlatMap
« Odpověď #97 kdy: 28. 09. 2016, 15:42:35 »
Ne tak úplně, bind je flatMap, jsou to jen různá pojmenování stejné operace (stejně jako join a flatten).
Spíš flatMap je speciální případ bindu, ne?

Pod flatMap myslím každej chápe operaci nad seznamy a nic jinýho.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Map vs. FlatMap
« Odpověď #98 kdy: 28. 09. 2016, 16:15:19 »
Ne tak úplně, bind je flatMap, jsou to jen různá pojmenování stejné operace (stejně jako join a flatten).
Spíš flatMap je speciální případ bindu, ne?

Pod flatMap myslím každej chápe operaci nad seznamy a nic jinýho.
Tak třeba flatMap ve Swiftu je i u Optional a chová se jako >>= (je to flatten.map). Java to má myslím taky tak. Suma sumárum ne "každej" to vztahuje jen na seznamy. Ale asi nemá smysl se o tom hádat, každý si může tu operaci pojmenovat, jak chce. Mně se třeba taky víc líbí "bind", a ve Swiftu píšu flatMap (u kolekcí i jiných monád) s vědomím, že jde o bind.

Re:Map vs. FlatMap
« Odpověď #99 kdy: 28. 09. 2016, 16:35:18 »
Tak třeba flatMap ve Swiftu je i u Optional a chová se jako >>= (je to flatten.map). Java to má myslím taky tak.
Scala určitě. Ale to je tím, že Optional je intuitivně seznam o 0<=n<=1 prvcích. Docela bych trval na tom, že "každý" programátor chápe flatMap jako mapování přes nějakou kolekci a ne jako úplně obecný bind - tj. "zřetězení v monadickém typu".

Můžeš se zkusit průměrného programátora zeptat, jestli když v javascriptu asynchronní fci na načítání něčeho přes HTTP vracející future předává url, jestli je to podle něj flatMap. Vsadím boty, že na tebe bude koukat jako na blázna ;)

Ale asi nemá smysl se o tom hádat, každý si může tu operaci pojmenovat, jak chce.
Souhlas. Ale běžný programátor podle mě ten obecný rozměr nevidí tak dobře jako ty. Nebo spíš vůbec. Takže když to tak budeš nazývat, spíš to povede k nedorozumění než naopak.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Map vs. FlatMap
« Odpověď #100 kdy: 28. 09. 2016, 16:59:28 »
Tak třeba flatMap ve Swiftu je i u Optional a chová se jako >>= (je to flatten.map). Java to má myslím taky tak.
Scala určitě. Ale to je tím, že Optional je intuitivně seznam o 0<=n<=1 prvcích. Docela bych trval na tom, že "každý" programátor chápe flatMap jako mapování přes nějakou kolekci a ne jako úplně obecný bind - tj. "zřetězení v monadickém typu".

Můžeš se zkusit průměrného programátora zeptat, jestli když v javascriptu asynchronní fci na načítání něčeho přes HTTP vracející future předává url, jestli je to podle něj flatMap. Vsadím boty, že na tebe bude koukat jako na blázna ;)

Ale asi nemá smysl se o tom hádat, každý si může tu operaci pojmenovat, jak chce.
Souhlas. Ale běžný programátor podle mě ten obecný rozměr nevidí tak dobře jako ty. Nebo spíš vůbec. Takže když to tak budeš nazývat, spíš to povede k nedorozumění než naopak.
Já to tak nenazývám, nejvíc se mi líbí >>=, dokonce jsem si pro něj vytvořil vlastní latexové makro (a pro další jako rybí operátor). Jen v podstatě říkám, na co jsem narazil v dokumentaci Swiftu u každé monády, totiž že flatMap=flatten.map, což tam beru jako konvenci.

ava

Re:Map vs. FlatMap
« Odpověď #101 kdy: 28. 09. 2016, 20:34:12 »
Scala určitě. Ale to je tím, že Optional je intuitivně seznam o 0<=n<=1 prvcích. Docela bych trval na tom, že "každý" programátor chápe flatMap jako mapování přes nějakou kolekci a ne jako úplně obecný bind - tj. "zřetězení v monadickém typu".

Netrvej, podle mě většina scalistů chápe flatMap jako bind (i když třeba název bind neznají), už třeba pro to, že for-comprehension funguje všude kde je definovaný flatMap, flatMap je definovaný na dost věcech ze základní knihovny (kolekce, Option, Future, Either (projekce), ...), a všechno tohle se o flatMapu dozví v knihách, tutoriálech atp. Jestli jsi teda to "každý" nedal do uvozovek, aby jsi mohl tvrdit, že tím každým myslíš všechny "běžné" programátory až na ty, kteří chápou flatMap jako bind..

Re:Map vs. FlatMap
« Odpověď #102 kdy: 28. 09. 2016, 21:13:13 »
podle mě většina scalistů chápe flatMap jako bind (i když třeba název bind neznají), už třeba pro to, že for-comprehension funguje všude kde je definovaný flatMap
Nějak nechápu strukturu tohodle argumentu.

Scalisti chápou, že X je vlastně Y, protože X je definované na kde čem?

Bind (v tom haskellovském monadickém smyslu) je definovaný tím, že splňuje monad laws:
Kód: [Vybrat]
Left identity: return a >>= f ≡ f a

Right identity: m >>= return ≡ m

Associativity: (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
To by mě teda zajímalo, kolik scalistů si s tímhle láme hlavu...

Radek Miček

Re:Map vs. FlatMap
« Odpověď #103 kdy: 28. 09. 2016, 21:51:29 »
podle mě většina scalistů chápe flatMap jako bind (i když třeba název bind neznají), už třeba pro to, že for-comprehension funguje všude kde je definovaný flatMap
Nějak nechápu strukturu tohodle argumentu.

Scalisti chápou, že X je vlastně Y, protože X je definované na kde čem?

Bind (v tom haskellovském monadickém smyslu) je definovaný tím, že splňuje monad laws:
Kód: [Vybrat]
Left identity: return a >>= f ≡ f a

Right identity: m >>= return ≡ m

Associativity: (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
To by mě teda zajímalo, kolik scalistů si s tímhle láme hlavu...

Otázkou je, co symbol ≡ přesně znamená (zejména, jak se ten symbol chová se seq)?

Re:Map vs. FlatMap
« Odpověď #104 kdy: 28. 09. 2016, 21:53:47 »
Otázkou je, co symbol ≡ přesně znamená (zejména, jak se ten symbol chová se seq)?
Znamená, že výraz na pravé a levé straně má vždy stejnou hodnotu.