Próbuję przetłumaczyć Strzały z biblioteki rdzenia Haskella na F # (Myślę, że jest to dobre ćwiczenie, aby lepiej zrozumieć Arrows i F #, i być może będę mógł je wykorzystać w projekcie, nad którym pracuję.) Jednak bezpośrednie tłumaczenie nie jest możliwe z powodu różnicy w paradygmatach. Haskell używa klas typu do wyrażania tych rzeczy, ale nie jestem pewien, co F # konstruuje najlepiej mapuje funkcjonalność klas typów z idiomami F #. Mam kilka przemyśleń, ale pomyślałem, że najlepiej jest go tu przywołać i zobaczyć, co uważano za najbardziej zbliżone do funkcjonalności.Jak mogę przetłumaczyć klasę typu Haskell na F #?
Dla tłumu tl: Jak mogę przetłumaczyć klasy typów (idiom Haskella) na F # idiomatic?
Dla tych zaakceptowaniem mojego długiego wyjaśnienia:
Ten kod z Haskell standardowych lib jest przykładem tego, co staram się tłumaczyć:
class Category cat where
id :: cat a a
comp :: cat a b -> cat b c -> cat a c
class Category a => Arrow a where
arr :: (b -> c) -> a b c
first :: a b c -> a (b,d) (c,d)
instance Category (->) where
id f = f
instance Arrow (->) where
arr f = f
first f = f *** id
Próba 1: Moduły, Simple Rodzaje Niech Wiązania
Mój pierwszy strzał w tym było po prostu map rzeczy nad bezpośrednio za pomocą modułów dla organizacji, jak:
type Arrow<'a,'b> = Arrow of ('a -> 'b)
let arr f = Arrow f
let first f = //some code that does the first op
To działa, ale traci na polimorfizmie, ponieważ nie wdrażam Kategorii i nie mogę łatwo wprowadzić bardziej wyspecjalizowanych Strzał.
Próba 1a: Refining użyciu podpisów i rodzajów
Jednym ze sposobów, aby poprawić pewne problemy z próba 1 jest użycie .fsi plik zdefiniowanie metod (tak rodzaje egzekwować łatwiej) i korzystać z niektórych proste wpisz ulepszenia, aby specjalizować.
type ListArrow<'a,'b> = Arrow<['a],['b]>
//or
type ListArrow<'a,'b> = LA of Arrow<['a],['b]>
ale plik FSI nie mogą być ponownie wykorzystane (aby wymusić rodzaje funkcji let związany) dla innych implementacjach, a typ zmiany nazwy/enkapsulacji rzeczy jest trudne.
Próba 2: Modele obiektowe i interfejsy
Racjonalizacja że F # jest zbudowany tak, aby OO również, może hierarchia typ jest właściwy sposób to zrobić.
type IArrow<'a,'b> =
abstract member comp : IArrow<'b,'c> -> IArrow<'a,'c>
type Arrow<'a,'b>(func:'a->'b) =
interface IArrow<'a,'b> with
member this.comp = //fun code involving "Arrow (fun x-> workOn x) :> IArrow"
Oprócz ile bólu może być, aby uzyskać to, co powinno być metody statyczne (jak komp i innych operatorów) zachowywać się jak metody instancji, istnieje również potrzeba wyraźnie uskok wyniki. Nie jestem też pewny, czy ta metodologia wciąż oddaje pełną ekspresję polimorfizmu klasy typu. Utrudnia to również używanie rzeczy, które MUSZĄ być statycznymi metodami.
Próba 2a: Refining użyciu rozszerzeń typów
Więc jeszcze jeden potencjalny dystynkcja jest zadeklarować interfejsów jako nagie, jak to możliwe, a następnie użyć metody rozszerzenie dodać funkcję do wszystkich typów wykonawczych.
type IArrow<'a,'b> with
static member (&&&) f = //code to do the fanout operation
Ach, ale to blokuje mi się za pomocą jednej metody dla wszystkich typów IArrow.Jeśli chciałbym nieco inny (& & &) dla ListArrows, co mogę zrobić? Nie próbowałem jeszcze tej metody, ale przypuszczam, że mogę śledzić (& & &), lub przynajmniej zapewnić bardziej wyspecjalizowaną wersję, ale mam wrażenie, że nie mogę wymusić użycia poprawnego wariantu.
Help me
Więc co mam zrobić tutaj? Czuję, że OO powinien być wystarczająco potężny, aby zastąpić klasy typów, ale nie potrafię wymyślić, jak to zrobić w F #. Czy któraś z moich prób była blisko? Czy któryś z nich jest "tak dobry, jak to tylko możliwe" i który będzie musiał być wystarczająco dobry?
"Jak przetłumaczyć klasy typów (idiom Haskella) na F # idiomatic code?" Kiepski pomysł. Powinieneś popatrzeć na * problem *, który próbujesz rozwiązać zamiast rozwiązania, które zdarzyło się używać klas typów i dowiedzieć się, jak go rozwiązać, korzystając z funkcji, którą zapewnia F #. –
@Jon Harrop To jest sedno pytania. Haskell rozwiązuje dziesiątki problemów z typami klas, a ja chciałem wiedzieć, jakie alternatywy F # mają rozwiązać podobną * klasę * problemów.Również port Arrow nie rozwiązuje żadnych problemów, a jedynie "Myślałem, że fajnie byłoby dowiedzieć się więcej o działalności Arrows". – CodexArcanum
Wtedy myślę, że byłoby naprawdę cenne, gdybyś mógł wyjaśnić niektóre problemy, które klasy typu rozwiązują i pytać ludzi, w jaki sposób rozwiążą te same problemy w F #. –