Czytałem Real World Haskell i zbliżam się do końca, ale kwestia stylu mnie dręczy z operatorami (.)
i ($)
.
Kiedy piszesz funkcję będącą kompozycją innych funkcji, piszesz ją tak:
f = g . h
Ale kiedy zastosujesz coś na końcu tych funkcji, piszę to w ten sposób:
k = a $ b $ c $ value
Ale książka napisałaby to tak:
k = a . b . c $ value
Dla mnie wyglądają na równoważne funkcjonalnie, robią dokładnie to samo w moich oczach. Jednak im więcej patrzę, tym częściej widzę ludzi piszących swoje funkcje w sposób, w jaki robi to książka: (.)
najpierw komponuj, a dopiero na końcu użyj, ($)
aby dodać wartość, aby ocenić partię (nikt nie robi tego z wieloma kompozycjami dolarowymi) .
Czy jest jakiś powód, by używać książek w sposób znacznie lepszy niż używanie wszystkich ($)
symboli? Czy jest tu jakaś najlepsza praktyka, której nie rozumiem? A może jest to zbędne i nie powinienem się tym w ogóle martwić?
źródło
k = a $ b $ c value
a . b $ c value
, że nie podoba mi się tak bardzo jak trzeci przykład, ale oszczędza kilka znaków.Odpowiedzi:
Chyba mogę odpowiedzieć na to autorytetem.
Nie ma specjalnego powodu. Bryan i ja wolimy redukować szumy liniowe.
.
jest cichszy niż$
. W rezultacie książka używaf . g . h $ x
składni.źródło
f.g.h
wolą raczej myśleć o nowym, sprytnym stworzeniuf(g(h()))
. Teraz wywołują nową, aczkolwiek anonimową funkcję, którą stworzyli, zamiast po prostu łączyć w łańcuch duży słownik gotowych wywołań funkcji, takich jak użytkownik PHP.W istocie są równoważne: pamiętaj, że
$
operator zasadniczo nic nie robi.f $ x
ocenia dof x
. Celem$
jest jego zachowanie związane ze stałością: prawostronna asocjacja i minimalny priorytet. Usunięcie$
i użycie nawiasów do grupowania zamiast pierwszeństwa wrostków, fragmenty kodu wyglądają następująco:k = a (b (c (value)))
i
k = (a . b . c) value
Powodem, dla którego preferujemy
.
wersję nad$
wersją, jest ten sam powód, dla którego preferujemy obie wersje powyżej bardzo ujętej w nawiasy wersji: atrakcyjność estetyczna.Chociaż niektórzy mogą się zastanawiać, czy użycie operatorów wrostków zamiast nawiasów jest oparte na jakiejś podświadomej chęci uniknięcia jakiegokolwiek możliwego podobieństwa do Lispa (tylko żartuję ... myślę?).
źródło
Dodam, że w
f . g $ x
,f . g
jest znaczącą jednostką składniową.Tymczasem w
f $ g $ x
,f $ g
nie jest znacząca jednostka. Łańcuch$
jest zapewne bardziej konieczne - najpierw uzyskać wynikg
zx
, następnie zrobićf
z nim, a następnie zrobićfoo
z nim, potem itpTymczasem łańcuch
.
jest prawdopodobnie bardziej deklaratywny iw pewnym sensie bliższy widokowi skoncentrowanemu na przepływie danych - skomponuj serię funkcji i ostatecznie zastosuj je do czegoś.źródło
$
Operator zachowuje się podobnie do<|
operatora w F #. Uważam, że oba są zdefiniowane tak samo, w rzeczywistości - w F #(<|) a b = a b
i Haskella $ b = a b
, które są zasadniczo równoważne.(<|) b a = a b
w języku F #, ponieważ jest używany tak[1; 2; 3; 4; 5] <| List.map ((+) 1)
, jakby służył pamięci.<|
Operator przekazuje wartość do funkcji, zamiast przekazywać funkcję do wartości - Twój przykładowy kod będzie działał z|>
operatorem.Myślę, że dla mnie odpowiedzią jest (a) porządek, jak powiedział Don ; i (b) stwierdzam, że kiedy edytuję kod, moja funkcja może skończyć się w stylu bez punktów, a wtedy wszystko, co muszę zrobić, to usunąć ostatnią,
$
zamiast cofać się i zmieniać wszystko. Niewątpliwie drobna uwaga, ale drobiazg.źródło
Jest interesująca dyskusja na ten temat w tym wątku haskell-cafe . Podobno istnieje mniejszość, która posiada punkt widzenia, że prawo asocjatywność o
$
to „po prostu źle” , a następnie wybierającf . g . h $ x
naf $ g $ h $ x
to jeden sposób side-stepping problem.źródło
$!
ma również „po prostu złe” prawidłowe skojarzenie - dlaczego znak $! operator prawostronny? .To tylko kwestia stylu. Jednak sposób, w jaki robi to książka, ma dla mnie większy sens. Składa wszystkie funkcje, a następnie stosuje je do wartości.
Twoja metoda po prostu wygląda dziwnie, a ostatnia
$
jest niepotrzebna.Jednak to naprawdę nie ma znaczenia. W Haskell jest zwykle wiele, wiele poprawnych sposobów na zrobienie tego samego.
źródło
Zdaję sobie sprawę, że to bardzo stare pytanie, ale myślę, że jest inny powód, o którym nie wspomniano.
Jeśli deklarujesz nową funkcję bez punktów
f . g . h
, wartość, którą przekazujesz, zostanie zastosowana automatycznie. Jeśli jednak napiszeszf $ g $ h
, to nie zadziała.Myślę, że powodem, dla którego autor preferuje metodę kompozycji, jest to, że prowadzi ona do dobrej praktyki budowania funkcji.
źródło