Przez kilka dni próbowałem owinąć głowę wokół paradygmatu programowania funkcjonalnego w Haskell. Zrobiłem to, czytając tutoriale i oglądając screencasty, ale tak naprawdę nic się nie trzyma. Teraz, ucząc się różnych języków imperatywnych / OO (takich jak C, Java, PHP), ćwiczenia były dla mnie dobrą drogą. Ale ponieważ tak naprawdę nie wiem, do czego jest zdolny Haskell, a ponieważ istnieje wiele nowych koncepcji do wykorzystania, nie wiedziałem od czego zacząć.
Jak się nauczyłeś Haskell? Co sprawiło, że naprawdę „przełamałeś lody”? Jakieś dobre pomysły na rozpoczęcie ćwiczeń?
Odpowiedzi:
Zamierzam zamówić ten przewodnik według poziomu umiejętności, który posiadasz w Haskell, od absolutnego początkującego do eksperta. Pamiętaj, że proces ten potrwa wiele miesięcy (lat?), Więc jest raczej długi.
Absolutny początkujący
Po pierwsze, Haskell jest zdolny do wszystkiego, z wystarczającymi umiejętnościami. Jest bardzo szybki (według mojego doświadczenia tylko C i C ++) i może być używany do wszystkiego, od symulacji po serwery, guis i aplikacje internetowe.
Jednak są pewne problemy, które łatwiej jest napisać dla początkującego w Haskell niż inne. Problemy matematyczne i programy do przetwarzania list są do tego dobrymi kandydatami, ponieważ do pisania wymagają jedynie podstawowej wiedzy Haskella.
Po pierwsze, niektórymi dobrymi przewodnikami do nauki podstaw Haskell są: samouczek z haskellem „Naucz się uczyć haskell” i pierwsze 6 rozdziałów z nauczeniem się haskell . Czytając je, bardzo dobrze jest rozwiązywać proste problemy z tym, co wiesz.
Kolejne dwa dobre zasoby to Programowanie Haskell od pierwszych zasad i Programowanie w Haskell . Oba zawierają ćwiczenia dla każdego rozdziału, więc masz małe proste problemy z dopasowaniem do tego, czego nauczyłeś się na kilku ostatnich stronach.
Dobrą listą problemów do wypróbowania jest strona problemów Haskell 99 . Zaczynają się one bardzo prosto i stają się coraz trudniejsze z biegiem czasu. Jest to bardzo dobra praktyka wykonywania wielu z nich, ponieważ pozwalają ćwiczyć umiejętności rekurencyjne i funkcje wyższego rzędu. Polecam pomijanie problemów wymagających losowości, ponieważ w Haskell jest to nieco trudniejsze. Sprawdź to pytanie SO, jeśli chcesz przetestować swoje rozwiązania za pomocą QuickCheck (patrz Pośredni poniżej).
Po wykonaniu kilku z nich możesz przejść do rozwiązania kilku problemów związanych z Project Euler . Są one sortowane według liczby osób, które je ukończyły, co jest dość dobrym wskaźnikiem trudności. Testują one twoją logikę i Haskella bardziej niż poprzednie problemy, ale nadal powinieneś być w stanie zrobić kilka pierwszych. Dużą zaletą Haskell przy tych problemach jest to, że liczby całkowite nie są ograniczone. Aby rozwiązać niektóre z tych problemów, przydatne będzie przeczytanie rozdziałów 7 i 8, aby nauczyć się Haskell.
Początkujący
Po tym powinieneś mieć dość dobrą kontrolę nad funkcjami rekurencji i wyższego rzędu, więc byłby to dobry czas, aby zacząć robić więcej rzeczywistych problemów. Bardzo dobrym miejscem do rozpoczęcia jest Real World Haskell (książka online, można również kupić wersję papierową). Znalazłem kilka pierwszych rozdziałów wprowadzonych zbyt szybko dla kogoś, kto nigdy wcześniej nie programował funkcjonalnie / nie używał rekurencji. Jednak dzięki praktyce, którą miałbyś podczas wykonywania poprzednich problemów, powinna być dla ciebie całkowicie zrozumiała.
Przeanalizowanie problemów zawartych w książce to świetny sposób na naukę zarządzania abstrakcjami i budowania komponentów wielokrotnego użytku w Haskell. Jest to niezbędne dla osób przyzwyczajonych do programowania obiektowego (oo), ponieważ normalne metody abstrakcji oo (klasy oo) nie pojawiają się w Haskell (Haskell ma klasy typów, ale bardzo różnią się od klas oo, bardziej jak interfejsy oo ). Nie sądzę, że dobrym pomysłem jest pomijanie rozdziałów, ponieważ każdy wprowadza wiele nowych pomysłów, które są używane w późniejszych rozdziałach.
Po chwili przejdziesz do rozdziału 14, przerażającego rozdziału monad (dum dum dummmm). Niemal każdy, kto uczy się Haskella, ma problem ze zrozumieniem monad, z powodu tego, jak abstrakcyjna jest ta koncepcja. Nie mogę wymyślić żadnej koncepcji w innym języku, która byłaby tak abstrakcyjna, jak monady w programowaniu funkcjonalnym. Monady pozwalają na ujednolicenie wielu pomysłów (takich jak operacje We / Wy, obliczenia, które mogą się nie powieść, parsowanie, ...) w ramach jednego pomysłu. Więc nie zniechęcaj się, jeśli po przeczytaniu rozdziału o monadach tak naprawdę ich nie rozumiesz. Przydało mi się czytać wiele różnych wyjaśnień monad; każdy daje nowe spojrzenie na problem. Oto bardzo dobra lista samouczków dotyczących monady . Bardzo polecam All About Monads , ale inne też są dobre.
Ponadto koncepcja naprawdę długo się zapełnia. Dzieje się tak dzięki użyciu, ale także z czasem. Uważam, że czasami sen na problemie pomaga bardziej niż cokolwiek innego! W końcu pomysł kliknie i będziesz się zastanawiać, dlaczego starałeś się zrozumieć koncepcję, która w rzeczywistości jest niezwykle prosta. To jest niesamowite, kiedy to się dzieje, a kiedy tak się dzieje, może się okazać, że Haskell jest twoim ulubionym imperatywnym językiem programowania :)
Aby upewnić się, że doskonale rozumiesz system typu Haskell, powinieneś spróbować rozwiązać 20 pośrednich ćwiczeń haskell . Ćwiczenia wykorzystujące zabawne nazwy funkcji takich jak „furry” i „banana” i pomagają dobrze zrozumieć niektóre podstawowe koncepcje programowania funkcjonalnego, jeśli jeszcze ich nie masz. Miły sposób na spędzenie wieczoru z bukietem papierów pokrytych strzałami, jednorożcami, kiełbasami i puszystymi bananami.
Pośredni
Kiedy zrozumiesz Monady, myślę, że dokonałeś przejścia z początkującego programisty Haskell na pośredniego haskellera. Gdzie więc iść? Pierwszą rzeczą, którą poleciłbym (jeśli jeszcze nie nauczyłeś się ich z nauki monad), są różne typy monad, takie jak Reader, Writer i State. Ponownie, Real world Haskell i All about monads doskonale to opisuje. Aby ukończyć trening monady, niezbędna jest znajomość transformatorów monad. Umożliwiają one łączenie różnych typów monad (takich jak czytnik i monada stanowa) w jedną. Na początku może się to wydawać bezużyteczne, ale po pewnym czasie będziesz się zastanawiać, jak żyłeś bez nich.
Teraz możesz dokończyć książkę Haskell z prawdziwego świata, jeśli chcesz. Pomijanie rozdziałów nie ma teraz większego znaczenia, pod warunkiem, że masz monady. Po prostu wybierz to, co Cię interesuje.
Mając wiedzę, którą posiadasz teraz, powinieneś być w stanie korzystać z większości pakietów na Cabal (przynajmniej te udokumentowane przynajmniej ...), a także z większości bibliotek dostarczanych z Haskell. Lista interesujących bibliotek do wypróbowania to:
Parsec : do analizowania programów i tekstu. O wiele lepsze niż używanie wyrażeń regularnych. Doskonała dokumentacja, zawiera także rozdział Haskell z prawdziwego świata.
QuickCheck : bardzo fajny program do testowania. Twoim zadaniem jest napisanie predykatu, który zawsze powinien być prawdziwy (np
length (reverse lst) == length lst
.). Następnie przekazujesz predykat QuickCheck, który wygeneruje wiele losowych wartości (w tym przypadku list) i sprawdzi, czy predykat jest prawdziwy dla wszystkich wyników. Zobacz także instrukcję online .HUnit : Testy jednostkowe w Haskell.
gtk2hs : Najpopularniejszy framework GUI dla Haskell, pozwala pisać aplikacje gtk w Haskell.
happstack : platforma programistyczna dla Haskell. Nie używa baz danych, zamiast magazynu typów danych. Całkiem dobre dokumenty (inne popularne frameworki to snap i yesod ).
Ponadto istnieje wiele koncepcji (takich jak koncepcja Monady), których powinieneś się nauczyć. Będzie to łatwiejsze niż nauka Monad za pierwszym razem, ponieważ twój mózg będzie przyzwyczajony do radzenia sobie z poziomem abstrakcji. Bardzo dobrym przeglądem do poznania tych pojęć wysokiego poziomu i ich wzajemnego dopasowania jest Typeclassopedia .
Dotyczy: interfejs taki jak Monady, ale mniej wydajny. Każda monada ma zastosowanie, ale nie odwrotnie. Jest to przydatne, ponieważ niektóre typy mają zastosowanie, ale nie są monadami. Ponadto kod napisany przy użyciu funkcji aplikacyjnych jest często łatwiejszy do skomponowania niż zapisanie równoważnego kodu przy użyciu funkcji Monada. Zobacz Functors, Applicative Functors i Monoids z podręcznika haskell.
Składany , przesuwny : Typeclasses że streszczenie wielu operacji list, tak, że te same funkcje mogą być stosowane do innych typów kontenerów. Zobacz także objaśnienie wiki haskell .
Monoid : Monoid to typ, który ma wartość zero (lub mempty) i zapisaną operację,
<>
która łączy dwa Monoidy razem, takie jakx <> mempty = mempty <> x = x
ix <> (y <> z) = (x <> y) <> z
. Są to tak zwane prawa tożsamości i stowarzyszenia. Wiele typów to Monoidy, takie jak liczby, zmempty = 0
i<> = +
. Jest to przydatne w wielu sytuacjach.Strzałki : strzałki są sposobem reprezentowania obliczeń, które pobierają dane wejściowe i zwracają dane wyjściowe. Funkcja jest najbardziej podstawowym rodzajem strzałki, ale istnieje wiele innych typów. Biblioteka ma również wiele bardzo przydatnych funkcji do manipulowania strzałkami - są one bardzo przydatne, nawet jeśli są używane tylko ze zwykłymi starymi funkcjami Haskell.
Tablice : różne zmienne / niezmienne tablice w Haskell.
ST Monada : pozwala pisać kod ze zmiennym stanem, który działa bardzo szybko, a jednocześnie pozostaje czysty poza monadą. Zobacz link po więcej szczegółów.
FRP: Functional Reactive Programming, nowy, eksperymentalny sposób pisania kodu, który obsługuje zdarzenia, wyzwalacze, dane wejściowe i wyjściowe (takie jak GUI). Ale niewiele o tym wiem. Rozmowa Paula Hudaka o yampie to dobry początek.
Jest wiele nowych funkcji językowych, na które powinieneś spojrzeć. Po prostu je wymienię , możesz znaleźć wiele informacji na ich temat z Google, wikibook haskell , strony haskellwiki.org i dokumentacji ghc .
Wiele Haskell opiera się na teorii kategorii , więc warto się temu przyjrzeć. Dobrym punktem wyjścia jest teoria kategorii dla informatyków . Jeśli nie chcesz kupować książki, artykuł autora jest również doskonały.
Na koniec będziesz chciał dowiedzieć się więcej o różnych narzędziach Haskell. Obejmują one:
Ucząc się tych wszystkich nowych bibliotek i pojęć, bardzo przydatne jest pisanie umiarkowanego projektu w Haskell. Może to być wszystko (np. Mała gra, analizator danych, strona internetowa, kompilator ). Praca nad tym pozwoli ci zastosować wiele rzeczy, których się teraz uczysz. Pozostajesz na tym poziomie przez wieki (tutaj jestem).
Ekspert
Dojście do tego etapu zajmie ci lata (cześć od 2009 roku!), Ale sądzę, że zaczynasz pisać prace doktorskie, nowe rozszerzenia ghc i wymyślać nowe abstrakcje.
Otrzymywać pomoc
Wreszcie na każdym etapie nauki istnieje wiele miejsc, w których można uzyskać informacje. To są:
Wniosek
Okazało się to dłużej, niż się spodziewałem ... W każdym razie uważam, że bardzo dobrym pomysłem jest opanowanie Haskell. To zajmuje dużo czasu, ale dzieje się tak głównie dlatego, że uczysz się zupełnie nowego sposobu myślenia. To nie jest jak nauka języka Ruby po nauce języka Java, ale jak nauka języka Java po nauce języka C. Odkryłem również, że moje umiejętności programowania obiektowego poprawiły się w wyniku nauki języka Haskell, ponieważ widzę wiele nowych sposobów abstrakcji pomysłów.
źródło
Monad
ma większą moc, ale także mniej kompozycyjny ... wiele osób korzysta z monad, w których mogliby uniknąć czystszegoApplicative
kodu. Większość rzeczy, które są,Functor
są równieżMonad
, ale nie używasz>>=
ireturn
kiedyfmap
to wystarczy, ponieważ to drugie prowadzi do znacznie prostszego kodu, jeśli możesz go użyć.Mój kolega miał dobre doświadczenie z Learn You a Haskell for Great Good! .
I sprawdź odpowiedzi tutaj zbyt
źródło
Oto dobra książka, którą możesz przeczytać online: Real World Haskell
Większość programów Haskell, które zrobiłem, ma na celu rozwiązanie problemów z Project Euler .
Pewna rada, którą czytałem nie tak dawno temu, była taka, że powinieneś mieć standardowy zestaw prostych problemów, które wiesz, jak rozwiązać (teoretycznie), a następnie za każdym razem, gdy próbujesz nauczyć się nowego języka, wdrażasz te problemy w tym języku.
źródło
Podobało mi się oglądanie tej 13-odcinkowej serii o programowaniu funkcjonalnym za pomocą Haskell.
C9 Wykłady: Dr. Erik Meijer - Podstawy programowania funkcjonalnego: http://channel9.msdn.com/shows/Going+Deep/Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1/
źródło
Aby dodać odpowiedzi innych - jest jedna przydatna, która pomoże ci w kodowaniu (na przykład przy rozwiązywaniu problemów z projektem Euler): Hoogle . Możesz użyć interfejsu wiersza polecenia lub interfejsu internetowego .
Wiersz poleceń
Po zainstalowaniu platformy Haskell koniecznie
cabal install hoogle
Przykład użycia Hoogle:
Masz funkcję
f x = 3 * x + 1
i chcesz ją zastosować(5 :: Int)
, a następnie zastosować do wyniku i do tego wyniku itd. I uzyskać nieskończoną listę tych wartości. Podejrzewasz, że może już istnieć funkcja, która może ci pomóc (ale nie specjalnie dla ciebief
).Ta funkcja byłaby typu,
(a -> a) -> a -> [a]
jeśli zajmief 5
luba -> (a -> a) -> [a]
zajmie5 f
(zakładamy, że funkcja dotyczy typów ogólnych, a nie tylkoInt
s)tak, funkcja, której potrzebujesz, już istnieje i jest wywoływana
iterate
. korzystasz z tego przeziterate func 5
!interfejs sieciowy
Wynik dla tego samego przykładu można znaleźć tutaj .
źródło
Programowanie Grahama Huttona w Haskell jest zwięzłe, dość dokładne, a jego lata nauki Haskella naprawdę pokazują. Prawie zawsze to, od czego polecam, ludzie zaczynają, bez względu na to, dokąd idziesz.
W szczególności rozdział 8 („Parsery funkcjonalne”) zapewnia prawdziwe podstawy do rozpoczęcia pracy z monadami i myślę, że jest to zdecydowanie najlepsze miejsce na rozpoczęcie, a następnie All About Monads . (Jednak w odniesieniu do tego rozdziału zwróć uwagę na erratę ze strony internetowej: nie możesz użyć tego
do
formularza bez specjalnej pomocy. Możesz najpierw dowiedzieć się o klasach typów i rozwiązać ten problem samodzielnie).Rzadko podkreśla się to dla początkujących w Haskell, ale warto dość wcześnie nauczyć się nie tylko korzystania z monad, ale także konstruowania własnych. Nie jest to trudne, a dostosowane mogą sprawić, że wiele zadań będzie prostszych.
źródło
Nie próbuj czytać wszystkich samouczków monad ze śmiesznymi metaforami. Sprawią, że jeszcze bardziej się pomieszasz.
źródło
Proponuję dołączyć do kanału irc #haskell i zadawać tam pytania. Tak nauczyłem się Haskella. Jeśli przejdziesz przez Real World Haskell, jak sugerowano powyżej, odpowiedzi w czasie rzeczywistym na twoje pytania bardzo pomogą. Wielu inteligentnych ludzi na #haskell pisze Haskell dla zabawy i zysku, więc dostaniesz dużo dobrego wkładu. Spróbuj!
źródło
To są moje ulubione
Haskell: Programowanie funkcjonalne z typami
Real World Haskell
źródło
Mogę dodatkowo polecić Yet Another Tutorial Haskell jako wprowadzenie.
Innym dobrym materiałem do nauki (prawdopodobnie na poziomie pośrednim), który bardzo mi pomógł i nie został wymieniony w innych odpowiedziach, o ile widzę, jest Typeclassopedia Brenta Yorgeya , którą można znaleźć w The Monad Reader (Issue 13)
Jest napisany w bardzo przystępnym stylu i zawiera (między innymi) następującą poradę wprowadzającą:
Sam Monad Reader jest absolutną skarbnicą dla programistów funkcjonalnych (nie tylko programistów Haskell).
źródło
Spróbuj napisać w nim łatwe programy.
Prawdopodobnie możesz znaleźć przykładowe zadania w różnych podręcznikach.
Nie polecałbym trzymania się podręczników Haskell / FP, po prostu spróbuj robić z nim proste rzeczy: obliczenia, manipulacje ciągami, dostęp do plików.
Po rozwiązaniu tuzina przełamałem lody :)
Następnie przeczytaj dużo na temat zaawansowanych pojęć (Monady, Strzałki, IO, rekurencyjne struktury danych), ponieważ haskell jest nieskończony i jest ich wiele.
źródło
Wydaje mi się, że uświadomienie sobie funkcji Haskella za pomocą przykładów jest najlepszym sposobem na rozpoczęcie przede wszystkim.
http://en.wikipedia.org/wiki/Haskell_98_features
Oto trudne typy, w tym monady i strzały
http://www.haskell.org/haskellwiki/Typeclassopedia
w przypadku rzeczywistych problemów i większych projektów zapamiętaj te tagi: GHC (najczęściej używany kompilator), Hackage (libraryDB), Cabal (system budowania), darcs (inny system budowania).
Zintegrowany system może zaoszczędzić Twój czas: http://hackage.haskell.org/platform/
baza danych pakietów dla tego systemu: http://hackage.haskell.org/
Wiki kompilatora GHC: http://www.haskell.org/haskellwiki/GHC
Po Haskell_98_features i Typeclassopedia myślę, że już możesz sam znaleźć i przeczytać dokumentację na ich temat
Nawiasem mówiąc, możesz chcieć przetestować rozszerzenie językowe GHC, które może być częścią standardu haskell w przyszłości.
to mój najlepszy sposób na naukę haskell. mam nadzieję, że ci to pomoże.
źródło
Proponuję zacząć od przeczytania samouczka BONUS , a następnie przeczytania Real World Haskell (online za darmo) . Dołącz do kanału IRC #Haskell na irc.freenode.com i zadawaj pytania. Ci ludzie są całkowicie przyjaźni dla początkujących i z czasem bardzo mi pomogli. Również tutaj, na SO, jest świetne miejsce do uzyskania pomocy w sprawach, których nie można pojąć! Staraj się nie zniechęcać, gdy kliknie, twój umysł zostanie wysadzony w powietrze.
Samouczek BONUS sprawi, że poczujesz się lepiej i przygotujesz się na emocjonującą jazdę, którą przynosi Real World Haskell. Życzę szczęścia!
źródło
Jeśli masz tylko doświadczenie z językami imperatywnymi / OO, sugeruję użycie bardziej konwencjonalnego języka funkcjonalnego jako odskoczni. Haskell jest naprawdę inny i musisz zrozumieć wiele różnych koncepcji, aby dostać się gdziekolwiek. Proponuję najpierw zająć się językiem w stylu ML (jak np. F #).
źródło
Pierwsza odpowiedź jest bardzo dobra. Aby dostać się na poziom eksperta, powinieneś zrobić doktorat z udziałem niektórych ekspertów.
Proponuję odwiedzić stronę Haskell: http://haskell.org . Znajdziesz tam wiele materiałów i wiele odniesień do najbardziej aktualnych rzeczy w Haskell, zatwierdzonych przez społeczność Haskell.
źródło