Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: fortran1986 20. 08. 2019, 11:37:44
-
Prepisujem jednu aplikaciu z F# do OCAML (kôli platformovej nezávislosti na .NET a možnosti kompilovania do natívneho kódu). Sú to síce príbuzné jazyky na prvý pohľad môže programátor nadobudnúť dojem že ide o rovnaký jazyk. Dokonca F# má aj nejaký režim kompatibility z OCAML, ktorý je, ale už neaktuálny. Ocaml má úplne inú syntax OOP proste OOP je v F# totálne prekopané. OCAML má tiež omnoho bohatšie možnosti vo funkcionálnom programovaní a krajšie funkcionálnejšie knižnice.
Mám teda otázku k OCAML (a možno neskôr pridám ďalšie) ako sa pomocou pattern matchingu zisťuje typ generickej premennej?
V F# som to robil tak že som ju skonvertoval (zaboxoval) na objekt a potom je tam špeciálny operátor :? ktorý slúži na zisťovanie typu. V Ocaml neviem ako sa zisťuje typ.
Ako by ste trebars toto prepisali do OCAML ?:
let printType (value : 'a) =
match box value with
| :? bool -> "Bool"
| :? string -> "String"
| :? int -> "Integer"
| _ -> "Unsupported type"
|> printfn "%s"
samozrejme ide teraz len o priklad tento kus kodu neplanujem nikde pouzit.
-
Nemám přímo praktickou zkušenost s OCAML, ale řekl bych, že tam ekvivalentní konstrukce chybí, už třeba proto, že v OCAML není konstrukce na downcasting (přetypování na potomka v objektové hiararchii). V F# se využívá možností .NET runtimu, který dokáže vrátit typová metadata k objektu, či identifikovat jeho typ.
V OCAML to budete pravděpodobně donucen nějak obejít - pokud je množina použitých typů předem známa, můžete použít discriminated union a ten pak testovat přes pattern matching, což je bohužel nepohodlné, protože budete muset data neustále zaobalovat a rozbalovat.
Jinou možností je využít objektového rozšíření OCAMLu, které je použitelné, pokud je množina typů (value: 'a) otevřená.
Tam byste třeba nadefinoval metodu to_string(), která v každém podtypu vrací jméno. I tak byste asi musel vytvořit zaobalovací typ.
-
samozrejme ide teraz len o priklad tento kus kodu neplanujem nikde pouzit.
Předem říkám, že OCaml ani F# neznám :) Jenom bych se chtěl zeptat, na co to chceš použít? Matchování úplně jakéhokoliv typu mi zavání úplně špatným návrhem - zatahováním OOP-like přístupu někam, kde nemá co dělat. Ve správném funkcionálním jazyce by ani nic jako "any type" být nemělo, všude by v takových situacích měl být sum type.
-
Ve správném funkcionálním jazyce by ani nic jako "any type" být nemělo
Určitě? Kdo to tvrdí? Pokud vím, ve FP se běžně pracuje se subobject classifier (sorry, českou terminologii v tomto případě neznám), který tak nějak přirozeně vede k “supertypu” (=any type), jenž se v jistém smyslu terminálním objektem příslušné kategorie. To jen tak na okraj, praktického významu to nejspíš nemá ;)
-
který tak nějak přirozeně vede k “supertypu” (=any type)
Které jazyky takový typ skutečně mají? (Předtím jsem se asi nevyjádřil úplně přesně - ne že by se taková entita nedala myslet, ale neuvědomuju si, že bych viděl někde s ní v opravdové praxi operovat)
To jen tak na okraj, praktického významu to nejspíš nemá ;)
No právě :)
-
který tak nějak přirozeně vede k “supertypu” (=any type)
Které jazyky takový typ skutečně mají? (Předtím jsem se asi nevyjádřil úplně přesně - ne že by se taková entita nedala myslet, ale neuvědomuju si, že bych viděl někde s ní v opravdové praxi operovat)
Agda tuším. Už si to pamatuju jen matně, ale je to nutnost, když chci mít topos typů a nad ním dobře definované (a well-behaved) operace. To se zrovna hodí i v praxi, akorát detaily asi většinou nebývají v jazyce explicitně.
-
akorát detaily asi většinou nebývají v jazyce explicitně.
Takže se asi shodnem, že to, co chce OP, smrdí nějakou chybou v návrhu, ne? :)
-
akorát detaily asi většinou nebývají v jazyce explicitně.
Takže se asi shodnem, že to, co chce OP, smrdí nějakou chybou v návrhu, ne? :)
Jestli dobře chápu jeho dotaz, tak to rozhodně smysl má, akorát neznám Ocaml.
-
Nemám přímo praktickou zkušenost s OCAML, ale řekl bych, že tam ekvivalentní konstrukce chybí, už třeba proto, že v OCAML není konstrukce na downcasting (přetypování na potomka v objektové hiararchii). V F# se využívá možností .NET runtimu, který dokáže vrátit typová metadata k objektu, či identifikovat jeho typ.
V OCAML to budete pravděpodobně donucen nějak obejít - pokud je množina použitých typů předem známa, můžete použít discriminated union a ten pak testovat přes pattern matching, což je bohužel nepohodlné, protože budete muset data neustále zaobalovat a rozbalovat.
Jinou možností je využít objektového rozšíření OCAMLu, které je použitelné, pokud je množina typů (value: 'a) otevřená.
Tam byste třeba nadefinoval metodu to_string(), která v každém podtypu vrací jméno. I tak byste asi musel vytvořit zaobalovací typ.
Ďakujem Vám na stackoverflow mi tiež potvrdili Vaše slová. Vraj typy sú v OCAML známe len v compile time a počas runtime sú to len o hodnoty a informácia o type tam nie je. A potom som si uvedomil že áno. Spomenul som si ako som kedysi pointermi rôznych typov dokázal prekonvertovať hodnoty na jednom mieste v pamati z jedného typu na iný len tým že som na to miesto v pamati ukázal pointermi rôznych typov. Takže napríklad 4 Bajty dokázali byť zároveň RGBA struct a zároveň 32-bit Integer
samozrejme ide teraz len o priklad tento kus kodu neplanujem nikde pouzit.
Předem říkám, že OCaml ani F# neznám :) Jenom bych se chtěl zeptat, na co to chceš použít? Matchování úplně jakéhokoliv typu mi zavání úplně špatným návrhem - zatahováním OOP-like přístupu někam, kde nemá co dělat. Ve správném funkcionálním jazyce by ani nic jako "any type" být nemělo, všude by v takových situacích měl být sum type.
Chcem si nasimulovať dynamické behové prostredie. V staticky typovanom OCAML.
Síce ja sa dogmaticky nedržím nejakých paradigiem. Ide mi o praktickú stránku veci. Je mi jedno ako. Len nech je to čo najmenej pracné a najviac efektívne
Ale to čo ste napísali ma napriek tomu zaujíma takže akým spôsobom by ste to riešili čisto funkcionálne.
-
Chcem si nasimulovať dynamické behové prostredie. V staticky typovanom OCAML.
Aha, ok, pak to dava smysl.
Ale to čo ste napísali ma napriek tomu zaujíma takže akým spôsobom by ste to riešili čisto funkcionálne.
Jak jsem rikal: sum type (https://en.wikipedia.org/wiki/Tagged_union). V tomhle pripade by teda musel mit variantu pro kazdy typ, ktery v tom dynamickem "subjazyce" ma byt.
Ale OCaml fakt neznam, treba to tam jde i jinak.