Nicméně oba jazyky jsou značně rozdílné. Např. OCaml kontroluje kompatibilitu modulů strukturálně (když má modul funkce správných názvů a typů, tak je to ok), zatímco F# nebo celý .NET kontroluje kompatibilitu tříd nominálně (nestačí, že má metody správných názvů a typů, ale musí být podtypem nějaké třídy nebo rozhraní).
5. 10. 2023, 11:22 editováno autorem komentáře
Nejenom. Rozdíl je v systému modulů, kde OCaml umožňuje moduly parametrizovat jinými moduly (v ML světě se tomu říká aplikativní nebo generativní funktory).
OCaml má silnejší typový systém (např. GADT, polymorfní varianty) a silnější typovou inferenci. Na druhé straně F# má podtypový polymorfismus a OCaml jen řádkový (row) polymorfismus.
OCaml 5 a novější má podporu pro efekty a jejich handlery, což AFAIK není možné udělat v .NET bez podpory runtimu. A lidi od MS zrovna nedávno oznámili, že podpora nebude: https://github.com/dotnet/runtimelab/issues/2398
Jak říká jeden kolega, nejlepší OOP je žádné OOP.
Nicméně vzhledem k tomu, že se moc nechytlo ani původní Kayovo (message-based) OOP, ani to založené na dědičnosti (novější jazyky jako Go, Julia nebo Rust dědění z konkrétních typů nemají), tak možná není to správné žádné.
Akademicky je nejlepší "restrictive OOP", na rozdíl od běžně rozšířeného "ampliative OOP", ale to by byla jalová diskuse.
A nie je to trochu cheating použiť foldl? V OCaml/F# je to kompletný algoritmus sumy.
Zaujímavé je, že to vytvorí funkciu pre typ aj pre inštanciu. (BTW, funguje aj haskellovský $ pre pipu). C# má tzv. extension methods, ale tam to je oveľa ťažkopádnejšie.
def List.sum' [Add α] [Inhabited α] (l : List α) := l.foldl (λ x y => x + y) default def main: IO Unit := do let vals: List Nat := [1, 2, 3, 4, 5] IO.println vals.sum' let vals: List Nat := [1, 2, 3, 4, 5] IO.println (List.sum' $ vals) let vals: List Int := [-2, -1, 0, 1, 2, 3, 4, 5] IO.println vals.sum' let vals: List Float := [1.1, 2.2, 3.3, 4.4, 5.5] IO.println vals.sum'