Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Vykladač 25. 07. 2018, 16:21:59
-
Ahoj, nevíte, jak udělat generický monad transformer v Pythonu? Mám
class MaybeT:
def __init__(self, M):
self.M = M
a rád bych vytvořil obecnou monádu, ale neumím to genericky, tj. bez odkazování na typ zabalené monády (např. List nebo Cont). Jde to vůbec (vzhledem k tomu, že jde o higher-kinded type, což Python nijak zvlášť nepodporuje)?
-
pythonu jsem už trochu odvyknul, ale nešlo by použít metaclasses pro vytvoření typu (třídy) transformované monády?
-
pythonu jsem už trochu odvyknul, ale nešlo by použít metaclasses pro vytvoření typu (třídy) transformované monády?
Jde to i bez metatříd.
-
Kdyz mi das svoji definici Maybe tak ti to muzu zkusit napsat. Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Samozrejme, jelikoz Monad v Haskellu je typova trida, a jsi v Pythonu, tak monada bude jenom neformalne definovane rozhrani (tj. trida ktera ma urcite metody).
-
Kdyz mi das svoji definici Maybe tak ti to muzu zkusit napsat. Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Maybe mám klasicky:
class Maybe(Monad):
def __init__(self, val):
self.val = val
def bind(self, func):
if self.val is None:
return None
else:
return func(self.val)
Chtěl bych použít MaybeT(List) (například) a výsledek pak klasicky jako jakoukoliv monádu. Klidně i přes ty metatřídy, co jsem koukal, jsou to v podstatě "třídy" dědící z type.
-
Kdyz mi das svoji definici Maybe tak ti to muzu zkusit napsat. Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Maybe mám klasicky:
class Maybe(Monad):
def __init__(self, val):
self.val = val
def bind(self, func):
if self.val is None:
return None
else:
return func(self.val)
Chtěl bych použít MaybeT(List) (například) a výsledek pak klasicky jako jakoukoliv monádu. Klidně i přes ty metatřídy, co jsem koukal, jsou to v podstatě "třídy" dědící z type.
to "return None" se mi moc nezdá
-
Kdyz mi das svoji definici Maybe tak ti to muzu zkusit napsat. Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Maybe mám klasicky:
class Maybe(Monad):
def __init__(self, val):
self.val = val
def bind(self, func):
if self.val is None:
return None
else:
return func(self.val)
Chtěl bych použít MaybeT(List) (například) a výsledek pak klasicky jako jakoukoliv monádu. Klidně i přes ty metatřídy, co jsem koukal, jsou to v podstatě "třídy" dědící z type.
to "return None" se mi moc nezdá
Jo, to je blbost, jak jsem to přepisoval z typovaného jazyka s implicitní konverzí. Nicméně na transformery to nemá vliv.
-
Kdyz mi das svoji definici Maybe tak ti to muzu zkusit napsat. Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Maybe mám klasicky:
class Maybe(Monad):
def __init__(self, val):
self.val = val
def bind(self, func):
if self.val is None:
return None
else:
return func(self.val)
Chtěl bych použít MaybeT(List) (například) a výsledek pak klasicky jako jakoukoliv monádu. Klidně i přes ty metatřídy, co jsem koukal, jsou to v podstatě "třídy" dědící z type.
Lepší by to bylo přes operátor konflace (TypTyp)2 → TypTyp.
-
Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Pleteš, ta rovnost neplatí.
-
Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Pleteš, ta rovnost neplatí.
Muzes to lepe vysvetlit? Tim Id myslim Identity monadu, viz http://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Identity.html (http://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Identity.html): "The purpose of the Identity monad is its fundamental role in the theory of monad transformers. Any monad transformer applied to the Identity monad yields a non-transformer version of that monad."
Jo, to je blbost, jak jsem to přepisoval z typovaného jazyka s implicitní konverzí. Nicméně na transformery to nemá vliv.
Proto jsem se ptal na to Maybe.. pokud tazatel neumi napsat Maybe (porad tam jeste chybi definice pure), mel by si nejdriv zkusit napsat tu, a pak teprve se poustet do transformeru.
Ja sam transformery moc neznam, ale jak jsem psal - kdyz mi ukazes, ze umis napsat normalni Maybe, tak ti muzu zkusit napsat MaybeT.
-
porad tam jeste chybi definice pure
To mají aplikativní funktory, myslíš unit? To tam přece je. Jen se to tak nejmenuje.
-
porad tam jeste chybi definice pure
To mají aplikativní funktory, myslíš unit? To tam přece je. Jen se to tak nejmenuje.
Ano, myslim implementaci pure nebo return.
Ale jestli myslis, ze to dela konstruktor, tak je to zase spatne.. Jak zkonstruujes instanci Nothing? Ja ten konstruktor beru jako datovy konstruktor pro typ Maybe, tedy Nothing | Just a, jenze pure vraci jenom Just a.
-
porad tam jeste chybi definice pure
To mají aplikativní funktory, myslíš unit? To tam přece je. Jen se to tak nejmenuje.
Ale jestli myslis, ze to dela konstruktor, tak je to zase spatne.. Jak zkonstruujes instanci Nothing? Ja ten konstruktor beru jako datovy konstruktor pro typ Maybe, tedy Nothing | Just a, jenze pure vraci jenom Just a.
To snad dělá ta nadtřída, ne? Ta by měla mít i svůj bind, fmap a join. Trochu si ujasni, co to monáda vlastně je. Ten transformer pak přijde sám.
-
porad tam jeste chybi definice pure
To mají aplikativní funktory, myslíš unit? To tam přece je. Jen se to tak nejmenuje.
Ale jestli myslis, ze to dela konstruktor, tak je to zase spatne.. Jak zkonstruujes instanci Nothing? Ja ten konstruktor beru jako datovy konstruktor pro typ Maybe, tedy Nothing | Just a, jenze pure vraci jenom Just a.
To snad dělá ta nadtřída, ne? Ta by měla mít i svůj bind, fmap a join. Trochu si ujasni, co to monáda vlastně je. Ten transformer pak přijde sám.
Dela? Opravdu? Jak to vis, kdyz nezname jeji definici?
Ja jsem chtel tazateli pomoct, ale nejdriv musi napsat, jak ma definovanou Maybe monadu. Protoze je mnoho moznosti, jak to udelat. Ty misto toho jen rozdavas rozumy, a jeste spatne (jelikoz pure nevraci nikdy Nothing, tak nemuze byt definovana v Monad, ale musi byt definovana v Maybe, protoze co je Nothing je taky definovano v Maybe).
-
porad tam jeste chybi definice pure
To mají aplikativní funktory, myslíš unit? To tam přece je. Jen se to tak nejmenuje.
Ale jestli myslis, ze to dela konstruktor, tak je to zase spatne.. Jak zkonstruujes instanci Nothing? Ja ten konstruktor beru jako datovy konstruktor pro typ Maybe, tedy Nothing | Just a, jenze pure vraci jenom Just a.
To snad dělá ta nadtřída, ne? Ta by měla mít i svůj bind, fmap a join. Trochu si ujasni, co to monáda vlastně je. Ten transformer pak přijde sám.
jelikoz pure nevraci nikdy Nothing, tak nemuze byt definovana v Monad
To je blábol, nadtřída klidně může prostě zavolat konstruktor, který může být polymorfní a fungovat jako unit. Radši ten transformer nepiš, ať do toho nevnášíš bordel.
-
To je blábol, nadtřída klidně může prostě zavolat konstruktor, který může být polymorfní a fungovat jako unit. Radši ten transformer nepiš, ať do toho nevnášíš bordel.
"Muze." Rozmysli si znova moji otazku - jak pak vytvoris instanci Nothing?
Ano, konstruktor muze fungovat jako unit, ale ne tak, jak je napsan v tride Maybe. Musel by dostat specialni parametr, ktery rika, jestli chces vytvorit instanci Nothing. A ten specialni parametr by musela nadtrida respektovat, coz je prinejmensim nepekne.
-
nadtřída klidně může prostě zavolat konstruktor, který může být polymorfní a fungovat jako unit.
ten specialni parametr by musela nadtrida respektovat, coz je prinejmensim nepekne.
Nemusela protože polymorfismus. Jsou i jiné praktické důvody, proč mít konstruktor pro unit. Nicméně talk is cheap, show me the code.
-
A je trochu zavadejici nazyvat operaci "pure" (nebo "return", jak je to v Haskellu spis historicky) jako "unit". Plete se to pak u monad, ktere se navic chovaji i jako monoid.
Nemusela protože polymorfismus. Jsou i jiné praktické důvody, proč mít konstruktor pro unit. Nicméně talk is cheap, show me the code.
Nevim, jak ti mohu ukazat kod, kdyz tvrdim, ze to co chces nejde dohromady s danou definici Maybe, jak byla zde predlozena. Naopak, ty bys mel ukazat kod, kdyz tvrdis, ze to mozne je.
-
A je trochu zavadejici nazyvat operaci "pure" (nebo "return", jak je to v Haskellu spis historicky) jako "unit". Plete se to pak u monad, ktere se navic chovaji i jako monoid.
O monády tu celou dobu jde a původní terminologie je unit (že si haskellisti a jiní vymysleli pure, return, flatmap apod. je irelevantní). A komu chování jako monoid, nebude to tím, že to je monoid? A k tomu kódu, genetický unit v nadtřídě vrací prostě self(arg), naprosto triviálně. To funguje i s tou třídou výše. Pro transformer to je ovšem k ničemu.
-
Vysel bych z toho, ze (pokud se nepletu) MaybeT Id = Maybe.
Pleteš, ta rovnost neplatí.
Muzes to lepe vysvetlit?
Tohle nějak zapadlo. Tam není rovnost, jen isomorfismus. X se taky nerovná Xx1 nebo X+0, i když je s nimi isomorfní.
-
monada bude jenom neformalne definovane rozhrani (tj. trida ktera ma urcite metody).
Monáda je regulérní nadtřída, jak jinak bys dostal fmap a join, když implementuješ jen unit a bind? Pro MF doporučuju začít s liftem, ten je nejjednodušší a automaticky dá unit.
-
To je zase srazka s autistou, jednou.. Co kdybys radeji misto vrtani se v definicich tazateli pomohl, kdyz nechces, abych to udelal ja?
Samozrejme, kazda monada je monoid. Ale prakticke monady v programovani (treba Maybe nebo List) jsou casto monoidy jeste v jinem smyslu, a pak se to unit plete. Proto taky vynalezli jinou terminologii.
Izomorfismus nebudu komentovat, to je cisty matematicky autismus. Monadu je asi pravda v Pythonu praktictejsi implementovat jako tridu nez jako interface (uz jsem pozapomnel, proc jsem z Pythonu presel k Haskellu, kde tyhle triviality nemusim resit), nicmene to nijak neresi problem, ze jsme zatim z tazatele nedostali jeji definici, natoz definici Maybe.
-
Samozrejme, kazda monada je monoid. Ale prakticke monady v programovani (treba Maybe nebo List) jsou casto monoidy jeste v jinem smyslu, a pak se to unit plete. Proto taky vynalezli jinou terminologii.
nedostali jeji definici, natoz definici Maybe.
Že se to tobě plete neznamená, že se to plete ostatním. Když neznáš ani základní definice, tak se nediv, že v tom máš guláš.
Kdyby ses trochu zamyslel, dojde ti, co v té nadtřídě je (to Maybe je správně a nejjednodušší možné).
A zkus méně ad hominem a víc relevantního obsahu.
-
pythonu jsem už trochu odvyknul, ale nešlo by použít metaclasses pro vytvoření typu (třídy) transformované monády?
Nešlo. Místo class MaybeT: tam má být def MaybeT: vracející anonymní třídu. Takto se to dělá v JS a v Pythonu to funguje úplně stejně (a je to nejelegantnější a zároveň idiomatické řešení).
-
Hosi, ty vase plky kolem pseudofunkcionalniho programovani jsou desne k smichu, zvlaste kdyz to z toho co pisete vubec neumite.
-
Místo class MaybeT: tam má být def MaybeT: vracející anonymní třídu.
Abych to upřesnil:
def MaybeT(M):
class MT(Monad):
...
return MT
V podstatě jde o lexikální uzávěr, akorát (meta)typu třída. Lépe to nejde.
-
To je blábol, nadtřída klidně může prostě zavolat konstruktor, který může být polymorfní a fungovat jako unit. Radši ten transformer nepiš, ať do toho nevnášíš bordel.
"Muze." Rozmysli si znova moji otazku - jak pak vytvoris instanci Nothing?
Ano, konstruktor muze fungovat jako unit, ale ne tak, jak je napsan v tride Maybe. Musel by dostat specialni parametr, ktery rika, jestli chces vytvorit instanci Nothing. A ten specialni parametr by musela nadtrida respektovat, coz je prinejmensim nepekne.
V Pythonu můžete místo __init__ použít __new__ a tam si můžete vrátit co chcete, jakýkoliv objekt, který vytvoříte z parametrů.
-
To je blábol, nadtřída klidně může prostě zavolat konstruktor, který může být polymorfní a fungovat jako unit. Radši ten transformer nepiš, ať do toho nevnášíš bordel.
"Muze." Rozmysli si znova moji otazku - jak pak vytvoris instanci Nothing?
Ano, konstruktor muze fungovat jako unit, ale ne tak, jak je napsan v tride Maybe. Musel by dostat specialni parametr, ktery rika, jestli chces vytvorit instanci Nothing. A ten specialni parametr by musela nadtrida respektovat, coz je prinejmensim nepekne.
V Pythonu můžete místo __init__ použít __new__ a tam si můžete vrátit co chcete, jakýkoliv objekt, který vytvoříte z parametrů.
__new__ nesouvisí s výše zmíněným “neproblémem” (poskytnutý kód byl v pořádku).