Studiuję Haskell w celu zrozumienia programowania funkcjonalnego, oczekując, że zastosuję wgląd w innych językach (głównie Groovy, Python, JavaScript).
Wybrałem Haskell, ponieważ miałem wrażenie, że jest on bardzo czysto funkcjonalny i nie pozwala na poleganie na stanie.
Nie zdecydowałem się uczyć Haskell, ponieważ byłem zainteresowany nawigacją po wyjątkowo sztywnym systemie typów.
Moje pytanie brzmi: czy system silnego typu jest koniecznym produktem ubocznym niezwykle czystego języka funkcjonalnego, czy jest to wybór niezwiązany z projektem szczególnie dla Haskell?
functional-programming
haskell
language-features
type-systems
Eric Wilson
źródło
źródło
Odpowiedzi:
Uważam, że zrozumienie systemu typu Haskell jest wzmacniaczem do zrozumienia programowania funkcjonalnego.
Rzecz w czysto funkcjonalnym programowaniu polega na tym, że przy braku efektów ubocznych, które pozwalają ci robić wszelkiego rodzaju rzeczy w sposób dorozumiany, czysto funkcjonalne programowanie sprawia, że struktura twoich programów jest bardziej wyraźna.
Haskell zapobiega wsuwaniu rzeczy pod dywan, zmusza cię do jawnego radzenia sobie ze strukturą twojego programu i uczy cię języka do opisywania tych struktur: języka typów. Zrozumienie typów, szczególnie bogatych jak Haskell, sprawi, że będziesz lepszym programistą w dowolnym języku.
Gdyby Haskell nie był mocno wpisany, pojęcia takie jak monady, funktory aplikacyjne i tym podobne nigdy nie zostałyby zastosowane do programowania.
źródło
Najbardziej dynamicznie typowanym językiem funkcjonalnym jest zapewne Schemat. To powiedziawszy, system typu Haskell jest wskaźnikiem jego czystości. To pytanie „jak mierzyć czystość?”. System typów Haskell pozwala łatwo oddzielić nieczyste działania
IO
. Aby to zrobić, potrzebujesz systemu typu statycznego.Powiedzmy jednak, że system typów Haskell nie ma nic wspólnego z programowaniem funkcjonalnym. Nadal byłoby szczytem pychy twierdzić, że system typów nie pomoże ci w tym przedsięwzięciu edukacyjnym. System typów Haskell jest bogaty i złożony, a tym bardziej interesujący w porównaniu do systemów typów C ++ i OCaml.
Czy to przeszkoda? Nie, myślę, że to atut. Spróbuj na przykład zastanowić się, jak poradzić sobie z lenistwem Haskella
IO
.źródło
Clojure jest dynamicznie pisany na maszynie i prawie tak czysty jak Haskell, więc istnieje dobry argument, że system typów Haskell był raczej wyborem projektowym niż absolutnym wymogiem. Oba zdecydowanie mają swoje mocne strony, więc możesz rozważyć Clojure, jeśli naprawdę nie lubisz sztywności Haskella (ale patrz poniżej).
Kiedy zacząłem używać Haskell, uważałem system typów za denerwujący i tolerowałem go tylko z powodu wnioskowania o typie. Wkrótce odkryłem, że wiele błędów typu kompilator narzekał na rzeczy, które i tak by nie działały, nawet gdyby kompilator pozwolił mi to zrobić (np. Przypadkowe użycie mapy zamiast concatMap). Potem odkryłem, że programy, które przeszły kontrolę typu, były zwykle poprawne lub przynajmniej bliskie poprawności. Miałem nawet leniwą fazę, w której dokonałem refaktoryzacji, zmieniając typ funkcji i pozwalając kompilatorowi powiedzieć mi, co jeszcze trzeba zmienić. W końcu zdałem sobie sprawę, że system typów Haskell był bardzo wyrazisty i zacząłem projektować moje programy wokół typów. To jest Święty Graal Haskell.
źródło
if
s icond
sz Scheme, które, jak sądzę, przenosi się również na Clojure.System typów Haskell jest kluczem do jego zdolności do izolowania efektów od czystego kodu. O ile nie możesz izolować efektów w inny sposób lub nie usuniesz efektów całkowicie, silny system statyczny jest wymagany dla czysto funkcjonalnego programowania.
Haskell jest bardzo dobrym przykładem języka z silnym, statycznym systemem typów. Jeśli chcesz szerokiej i zaokrąglonej edukacji w zakresie informatyki, a zwłaszcza projektowania języków programowania, Haskell byłby doskonałym wyborem jako jeden z języków, których powinieneś się uczyć.
System typów nie powinien stanowić dużej przeszkody. Ludzie, którzy programują, często używają dynamicznych języków i przestrzegają konwencji pisania, które można kodować za pomocą systemu typów Haskell. Haskell oferuje również wnioskowanie o typie, które łagodzi gadatliwość w porównaniu do języków takich jak C ++ i Java. Gdy pojawi się komunikat o błędzie, kompilator informuje tylko w czasie kompilacji, co język z typami dynamicznymi powiedziałby w czasie wykonywania.
Przeciwieństwem dynamicznego systemu typów jest statyczny system typów, a nie silny system typów. System typu silnego jest przeciwieństwem systemu typu słabego.
źródło
Od razu powie ci, kiedy popełniasz głupie błędy. To jest pomocne. Pracowałem w Racket (Schemat) w ostatnim semestrze i wiele razy zdałem niezrozumiały s-exp, w którym spodziewałem się sparsowanego ast do jakiejś funkcji w moim tłumaczu, i to pokazało się tylko w moim średniej wielkości zestaw testowy. Gdybym miał jakieś statyczne pisanie, natychmiast zwróciłbym na to uwagę.
Oczywiście, błędy logiczne nie mogą być naprawdę wychwycone przez system typów, ale liczba sposobów, w które można zepsuć, jest znacznie zmniejszona.
Wnioskowanie typu pozwala również zignorować system typów, jeśli chcesz. Nadal tam jest, ale nie wymaga aktywnego wkładu z twojej strony. Nadal pomocne jest zrozumienie typów funkcji, ale poprawny kod będzie działał dobrze.
Czystość Haskella jest zakodowana w systemie typów. Monada IO jest konstrukcją na poziomie typu, która zatrzymuje wyciekanie nieczystego kodu do czystych funkcji, więc czystość jest gwarantowana przez system typów.
źródło
Bycie „funkcjonalnym” językiem oznacza (oprócz innych rzeczy), że funkcje są pierwszorzędnymi obiektami w tym języku.
Bycie „czystym” językiem oznacza, że funkcje są funkcjami matematycznymi (w przeciwieństwie do procedur) - przy tych samych danych wejściowych zawsze dają takie same wyniki.
„Czysty język funkcjonalny” to taki, w którym trzymają się oba powyższe. Nic mi nie wiadomo o „wyłącznie przy pomocy ly języku funkcjonalnej”.
System silnego typu to jeden czysty sposób na uzyskanie czystego, ale praktycznego języka. Typy pomagają kompilatorowi w określaniu optymalizacji, oprócz dalszego zapewniania poprawności. (Ale to nie jedyny sposób - clojure jest czysty, ale nie ma tak silnego systemu typów jak Haskell.)
Jeśli przeszkadza Ci system typów, sugeruję wypróbowanie bardziej dynamicznego języka, takiego jak Scheme, lub skorzystanie z systemu wnioskowania typu Haskell.
źródło
Tak, system typów jest niesamowitym atutem. Bardzo trudno byłoby nawet opisać, jak działają monady lub jak działają niektóre kombinatory bez systemu typów. Zastanów się, ile samouczków na temat Haskell najpierw poprosi cię o rozważenie rodzaju omawianej funkcji za pomocą: t na REPL. Jest to po prostu niedostępne w dynamicznie pisanym języku. Jasne, cała złożoność systemu typów wciąż istnieje. Monada wciąż jest monadą. Ale język postanowił umyć ręce i nie udzielić żadnej pomocy. Jesteś sam, kolego. Nie pukam dynamicznie pisanych języków. Bardzo ich kocham. Schemat jest par excellance elektronarzędzi. Ale zauważysz, że kiedy mówimy o rzeczach takich jak monady w dynamicznych językach, często wymyślamy zapisdo opisu rodzaju procedur. Funkcjonalny programista będzie walczył z typami w taki czy inny sposób. Narzędzie do sprawdzania typu Haskell zapewnia tylko dobre narzędzia do nauczenia się, jak to zrobić.
źródło