Haskell dla dzieci
Na Reddicie znalazłem dziś taką wypowiedź:
Ja również uczę 10-13 latki programowania w Haskellu, na lekcjach pod nazwą „pracownia gier wideo” [...].
Wybrałem Haskella między innymi dlatego, że dzisiejsze dzieci będą aplikować o pracę za pięć lat a nie za tydzień, więc powinniśmy ich uczyć dróg przyszłości a nie antycznych i skazanych na zapomnienie metod używanych w przemyśle dzisiaj.
– blackh
Zdaję sobie sprawę z kontrowersyjności tego zdania. Szczerze mówiąc nawet nie spodziewałem się takiej wypowiedzi kiedykolwiek zobaczyć. Dalej w wątku na reddicie jest uzasadnienie:
Ucząc dzieci w tym wieku byłoby przestępstwem planowanie im kariery i zaczynanie przyuczania do zawodu. Znacznie ważniejsze od programowania funkcyjnego jest przygotowanie matematyczne i logiczne, i temu nie można zaprzeczyć.
– cdsmiths
Chciałbym mieć możliwość przyglądnięcia się zajęciom z dziećmi prowadzonym przez obu panów.
Haskell praca: SkrivaPå (powtórka)
Kiedyś już zamieściłem tutaj ogłoszenie o pracy, przyszedł czas, by je powtórzyć! SkrivaPå rozwija się, potrzebujemy więcej ludzi do pomocy!
Więc jeszcze raz nawołuję:
Poszukujemy jednego albo dwóch programistów do pomocy przy tworzeniu serwisu SkrivaPå, internetowej aplikacji służącej do podpisywania dokumentów przez Internet oraz ogólnie zarządzania procesami kontrakcyjnymi dla biznesu. Jesteśmy dobrze zapowiadającym się startupem polsko-szwedzkim w czasie bardzo szybkiego rozwoju. Mamy nadzieję na wspólną zabawę Haskellem oraz Twój kreatywny wkład.
Będziesz pracował(a) na swoim komputerze, w dowolnym miejscu świata. Jeśli mieszkasz w Sztokholmie to możesz nawet w naszym biurze. W Krakowie zaś możemy umówić się w kawiarni. Jak przystało na firmę internetową będziemy się porozumiewać głównie przez Google Docs, Skype oraz email.
Warunki
Start: jak najszybciej
Czas trwania: 3 miesiące
Płaca: do negocjacji
Godziny: 20h-40h tygodniowo (chętnie również studenci)
Aktualnie używane technologie to głównie:
Jeśli tak ja my uwielbiasz Haskella, napisz do nas!
Kontakt: autor tego bloga.
Haskell kompilacja do exe
Kompilacja programów przy użyciu GHC jest bardzo prosta. Należy dodać opcję --make i gotowe.
Potrzebujemy najpierw źródła zawierającego funkcję main, na przykład:
main = putStrLn "Hello world"
Jeśli powyższe linijki znajdą się w pliku HelloWorld.hs, to można go skompilować komendą:
ghc --make HelloWorld.hs
a potem uruchomić:
c:\>HelloWorld.exe Hello world c:\>_
Gotowe!
Używanie funkcji map
Funkcja map każdy element na liście zamienia na inny element, obliczony jako funkcja oryginalnego.
Przykład:
> map (+2) [1,5,10] [3,7,12]
ogólnie:
map f [x1, x2, ...] == [f x1, f x2, ...]
Ciekawą własnością funkcji map jest to, że nie zmienia ona struktury. Znaczy to, że długość listy wynikowej będzie taka sama jak listy-argumentu.
Warto w tym miejscu wspomnieć o dwóch pochodnych funkcji map. Jedna to mapM:
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
która zasadniczo działa tak jak map, ale przy okazji podmiany każdego elementu pozwala na efekty uboczne (w monadzie).
Druga to fmap, funkcja klasy Functor, która jest uogólnieniem powyższej koncepcji do działania na dowolnej strukturze. Przykład:
> fmap (+2) (Nothing) Nothing > fmap (+2) (Just 5) Just 7
Co jeszcze warto wiedzieć o map, fmap, mapM i podobnych?
Liczby pierwsze
Najprostszy sposób na wygenerowanie liczb pierwszych:
primes :: [Integer]
primes = sieve [2..]
where
sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
Stała primes jest nieskończoną listą liczb, dlatego warto skorzystać tylko z kilku jej elementów:
print (take 5 primes)
Więcej na temat liczb pierwszych na stronie Prime numbers.
Liczenie elementów listy
Dziś początek nowej serii postów: odpowiedzi na pytania wyszukiwarek. WordPress podpowiada jakie zapytanie pozwoliło znaleźć mojego bloga. Skoro jest pytanie, będzie zatem odpowiedź!
Pytanie na dziś: „liczenie elementów listy haskell”.
Odpowiedź: funkcja length. Można jej użyć tak:
GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Prelude> print (length [1,2,3]) 3
Warto jeszcze sprawdzić typ tej funkcji:
Prelude> :t length length :: [a] -> Int
Ciekawe czy statystyki wizyt na blogu podskoczą :)
Monadic ACID
Happstack zawiera ciekawą propozycję trwałości danych nazwaną Monadic ACID. Nie jest to ani RDMS, ani noSQL. Myślę, że MACID to ciekawa propozycja w dziedzinie trwałości danych. Poniżej króta instrukcja, jak korzystać z MACID w Happstack.
Zadeklaruj dane:
> $(deriveAll [''Show, ''Eq, ''Ord, ''Default] > [d| > -- |GuestBookEntry: simple guest book entry > data GuestBookEntry = GuestBookEntry > { author :: String > , message :: String > , date :: ClockTime > } > > -- |GuestBook: a list of GuestBookEntry > newtype GuestBook = GuestBook { guestBookEntries :: [GuestBookEntry] } > |])
Zapewnij trwałość i wersjonowanie obiektów:
> $(deriveSerialize ''GuestBookEntry) > instance Version GuestBookEntry > > $(deriveSerialize ''GuestBook) > instance Version GuestBook
Przykładowa funkcja zapytania do bazy danych:
> readGuestBook :: Query GuestBook GuestBook > readGuestBook = ask
Przykładowa procedura modyfikacji bazy danych:
> addGuestBookEntry :: GuestBookEntry -> Update GuestBook () > addGuestBookEntry e = modify $ \(GuestBook gb) -> (GuestBook (e:gb))
Co ciekawe powyższe dwie funkcje mogą być dowolnie skomplikowane i używać pełnej gamy możliwości Haskella, co czyni z nich potężne procedury składowane.
Teraz stwórz listę metod, których będziesz używać do interakcji z bazą danych. Na tej liście muszą się znaleźć wszystkie przewidziane zapytania oraz modyfikacje.
> $(mkMethods ''GuestBook ['readGuestBook, 'addGuestBookEntry])
Rekord GuestBook zadeklaruj jako komponent aplikacji:
> -- |make Guestbook its own Component > instance Component GuestBook where > type Dependencies GuestBook = End > initialValue = defaultValue
Modyfikacje bazy danych wykonuje się przy użyciu konstrukcji update:
> let entry = GuestBookEntry {...} > update $ AddGuestBookEntry entry
A zapytania przy użyciu query:
> guestBook <- query $ ReadGuestBook > showAsHtml guestBook
Różnica między query a update jest prosta: query nie modyfikuje zawartości bazy danych, natomiast update ma taką możliwość. Obie funkcje są synchronizowane na bazie danych, jednak update jest również trwałe (ale przez to wolniejsze).
Moje doświadczenie z MACID sugerują następującą listę zalet i wad:
Zalety:
- nie trzeba ustawiać bazy SQL
- dane są statycznie typowane
- językiem zapytań jest Haskell
- językiem procedur składowanych jest również Haskell
Wady:
- rozmiar danych ograniczony wielkością dostępnej pamięci
- nie jest to architektura rozproszona
Z praktyki wiem, że MACID w wydaniu Happstack jest idealny do rozpoczęcia pracy nad aplikacją internetową. Odpada problem administracji zewnętrznej bazy danych!
Zaś gdy ilość danych urośnie, będzie można z pełną świadomością wybrać architekturę: czy standardowa relacyjna baza danych, czy coś z dziedziny noSQL, a może jakaś hybryda?
Haskell praca: SkrivaPå
Poszukujemy jednego albo dwóch programistów do pomocy przy tworzeniu serwisu SkrivaPå, internetowej aplikacji służącej do podpisywania dokumentów przez Internet oraz ogólnie zarządzania procesami kontrakcyjnymi dla biznesu. Jesteśmy dobrze zapowiadającym się startupem polsko-szwedzkim w czasie bardzo szybkiego rozwoju. Mamy nadzieję na wspólną zabawę Haskellem oraz Twój kreatywny wkład.
Będziesz pracował(a) na swoim komputerze, w dowolnym miejscu świata. Jeśli mieszkasz w Sztokholmie to możesz nawet w naszym biurze. W Krakowie zaś możemy umówić się w kawiarni. Jak przystało na firmę internetową będziemy się porozumiewać głównie przez Google Docs, Skype oraz email.
Warunki
Start: jak najszybciej
Czas trwania: 3 miesiące
Płaca: do negocjacji
Godziny: 20h-40h tygodniowo (chętnie również studenci)
Aktualnie używane technologie to głównie:
Jeśli tak ja my uwielbiasz Haskella, napisz do nas!
Kontakt: autor tego bloga.
Platformy webowe dla Haskella
Haskell może jeszcze nie ma swoich Railsów, ale za to prawdopodobnie jest językiem, który posiada najwięcej web frameworków. Dzielą się one na dwie kategorie: niedokończone oraz porzucone. Krótki przegląd alfabetyczny:
Zobaczymy, która platforma okaże się zwycięska!
Instalacja GHC w wersji minimalnej
Dzisiaj zainstalujemy najnowsze GHC 6.12.2 oraz Happstack na czystej maszynie Ubuntu 8 (gdyż taką mam dostępną). Użylibyśmy Haskell Platform, ale ponieważ chcemy mieć najnowszy kompilator, więc instalację przeprowadzimy ręcznie.
Najpierw zainstalujemy potrzebne pakiety systemowe. Ja do ich listy doszedłem metodą prób i błędów:
sudo apt-get install libc6-dev libgmp3c2 zlib1g-dev libgmp3c2-devel
W Linuxie nic nie może po prostu działać, więc poprawimy jedną drobnostkę:
pushd /usr/lib sudo ln -s libgmp.so.3 libgmp.so popd
Ściągamy binarną dystrybucję GHC, konfigurujemy oraz instalujemy w katalogu użytkownika:
wget http://haskell.org/ghc/dist/6.12.2/ghc-6.12.2-i386-unknown-linux-n.tar.bz2 tar -xjf ghc-6.12.2-i386-unknown-linux-n.tar.bz2 cd ghc-6.12.2 ./configure --prefix=/home/admin make install
Od teraz w katalogu ~/bin będą znajdować się wszystkiego programy związane z Haskellem. Dodajemy ten katalog do zmiennej PATH:
echo 'export PATH=$PATH:/home/admin/bin' >> .bashrc . .bashrc
Teraz zainstalujemy manager pakietów Cabal:
wget http://www.haskell.org/cabal/release/cabal-install-0.8.2/cabal-install-0.8.2.tar.gz tar -xzf cabal-install-0.8.2.tar.gz cd cabal-install-0.8.2 bash bootstrap.sh
Po kompilacji w katalogu ~/.cabal/bin powinien znaleźć się wykonywalny program cabal. Żeby było łatwiej tworzymy dowiązanie symboliczne do katalogu ~/bin:
ln -s .cabal/bin/cabal /home/admin/bin
Teraz pierwsze uruchomienie i inicjalizacja:
cabal update
Powstał początkowy plik ~/.cabal/config, dodajemy do niego flagę, która programy zbudowane w ~/.cabal/bin automatycznie dowiąże do ~/bin:
echo symlink-bindir: /home/admin/bin >> ~/.cabal/config
Zainstalujmy jeszcze coś ciekawego. Najpierw happy (gdyż jest potrzebny dla happstack):
cabal install happy
A teraz happstack:
cabal install happstack
Minimalna instalacja Haskella dla web developmentu gotowa!