Ugyhogy ehelyett azt a kozepesen izgalmas temat fogjuk boncolgatni, hogy a Haskell rovid uton elsoszamu kedvenc programnyelvemme lepett elo, pedig meg nem is programoztam benne igazan (sajnos ez az egyetemi system itt nem igazan up-to-date, ugyhogy a textmodos teletype-stylon kivul mas outputot meg nem igazan sikerult kicsikarnom a dologbol, ez nem erositi eppen a motivaciot). Na de ami kesik, (remelhetoleg) nem mulik.
Kezdjuk talan azzal a nemileg sokkolo eszrevettel, hogy a Haskell, amely nevet egyebkent Haskell Brooks Curry amerikai matematikusrol kapta, akirol most megtudtam hogy Hilbert volt a temavezetoje; ez azert eleg impozans. Es aki tovabba eleme a valaha elt emberek azon nagyon szuk reszhalmazanak, akinek a kereszt- es a vezetekneverol is neveztek el programozasi nyelvet. Eloszor azt akartam irni, hogy az egyetlen, de Pascal is erre a sorsra jutott ; viszont Pascal azert azt nem mondhatja el, hogy ezen tul a vezeteknevebol meg iget is faragtak volna (currying, lasd meg googling...). Tehat azt akartam mondani, hogy a Haskell (a nyelv :) sokkal alkalmasabb matematikai fogalmak leirasara, mint mondjuk a kifejezetten erre a celra fejlesztett CAS-ok nyelvei (az epp nem regen "emlitett" Maple, vagy a Mathematica), es persze gyorsabb is, meg nem kerul sokezer dollarba sem. Es ez a nem mindegy.
A Haskell-rol azt szoktak mondani egy mondatban, hogy lazy, funkcionalis, pure, (ja, es statically typed, ezt elfelejtettem. Ezentul viszont rozsaszinbe' fogok irni...) meg programnyelv. Ebbol a masodik azt jelenti hogy a fuggvenyek pont ugyanugy viselkednek mint barmely mas ertek ("functions are first-class citizens"), at lehet oket adni parameterkent, kombinalni lehet oket, stb. Pl van egy ilyen elso ranezesre nem tul erdekfeszito fuggveny, ami a $ nevre hallgat, es ez a definicioja:
($) :: (a->b) -> a -> b
f $ x = f x
Magyarul, a bemenete egy fuggveny meg egy ertek, es a kimenete az hogy raalkalmazza a fuggvenyt az ertekre. Az elso sor a fenti definiciobol opcionalis, mert a compiler ki tudja talalni magatol is hogy mire gondoltunk :). A dolog ertelme, hogy a
$-nak a leheto legalacsonyabb precedenciaja van az osszes operatorok kozott, es igy gyakran sokkal kevesebb zarojellel meg lehet uszni, ami sokkal olvashatobb (es amugy is, vizualisan baratsagosabb) kodot eredmenyez. Hasonlo meg a . (pont) operator, ami meg a fuggvenykompocio:
(.) :: (b->c) -> (a->b) -> (a->c)
(f.g) x = f (g x)
Itt az elso sorban az utolso zarojelpar igazabol felesleges, es az
f (g x) helyett akar azt is irhattam volna hogy f $ g x. Azt akkor most nyomatekositanam, mert talan konnyu atsiklani folotte, hogy ezek a kodreszletek teljesen validak, nem holmi pszeudokod, akar a ket sor(ok) egyutt, akar csak a masodik(ak).A "pure" azt jelenti hogy nincsenek side-effekt-ek: adott fuggveny adott bemenetre mindig ugyanazt a kimenetet adja (tehat pl nincsenek globalis valtozok sem, stb). Ez elsore ilyesztonek tunhet, mert pl hogy csinalunk akkor IO-t (a getchar fuggveny nem eppen igy viselkedik...), de a dolog nagyon kiforrottan van megoldva (a kulcsszo a monad, mely fogalom a kategoriaelmeletbol szarmazik, es jo peldaja (lesz) annak hogy egeszen meglepo modon lehet neha egeszen elszallt matematikat alkalmazni a gyakorlatban;
tovabba motivaciokent szolgal / fog szolgalni egesz programozo-generaciok szamara hogy kategoriaelmeletet tanuljanak :), es az elonyok oriasak: a tipikusan elofordulo bugok jelentos hanyada innentol fogva elo sem fordulhat.
A "lazy" azt jelenti, hogy csak akkor all neki kiszamolni dolgokat a program, amikor szukseg is van a konkret adatra. Pl definialhatunk vegtelen adatstrukturakat gond nelkul, amig csak egy veges reszuket hasznaljuk. Be kell hogy valljam ennek annyira sok ertelmet meg nem lattam, de baj nem lehet belole, es allitolag hasznos. Azert alljon itt egy (ertelmetlen) pelda:
take 137 $ cycle "whatthefuck"
ez egy 137 karakter hosszu stringet ad nekunk, mely ugy kezdodik hogy "whatthefuckwhatthefuckwhatthe..." (a take 137 nelkul egy vegtelen hosszu stringet kapnank, amely szinten mukodne egyebkent, csak sokaig tart kiprintelni...)
Meg van sok okossag beepitve a rendszerbe, amikre most nem terek ki, egyreszt mert nem ertem mindet :), masreszt ez mar igy is egy nagyon hosszu bejegyzes. De talan megprobalok osszedobni valami bugyuta peldaprogramot ide:
data Tree a = Leaf a | Branch (Tree a) (Tree a)
leaves (Leaf x) = [x]
leaves (Branch s t) = leaves s ++ leaves t
mapt f (Leaf x) = Leaf (f x)
mapt f (Branch s t) = Branch (mapt f s) (mapt f t)
Ez a program binaris fakat tud manipulalni. Eloszor definialtam egy binaris fa adattipust, amelynek a levelein
a tipusu dolgok csucsulnek (itt a paramater; akarmilyen tipus lehet, pl binaris fa is...). A leaves fuggveny (tipusa Tree a -> [a]) visszadja a leveken csucsulo objektumokat balrol jobbra rendezve egy listaban.A
mapt fuggveny (tipusa (a->b) -> Tree a -> Tree b) pedig minden levelre raenged egy fuggvenyt. Tehat pl ha t az egy olyan binaris fa, aminek levelein a megfelelo szamok vannak 0-tol 7-ig (binaris reprezentacio, aki idaig eljutott nyilvan erti :), akkor az a sor, hogy
leaves $ mapt (<3) t
(nemtom figyelitek-e a kodnak alcazott romantikat :) azt eredmenyezi hogy
[True,True,True,False,False,False,False,False]
(love hint:
(<3) :: (Ord a, Num a) => a -> Bool :)

6 comments:
http://www.willamette.edu/~fruehr/haskell/evolution.html
ez remelem megvolt :)
(wv: ubrnb)
ja megvolt. es te most talaltad, vagy mar korabbrol?
korabbrol
nekem is volt egy fellangolasom, de vegul nem foglalkoztam vele tul sokat
(wv: beslbfkl)
szeintem kurvajo, es most azt tervezem, hogy sokat fogok vele foglalkozni (persze ezt mar vagy fel eve tervezem, de most epp jobban :)
Halálos ez a szerelem
úgy kell ez
nagyon kell ez
énnekem
Ne mondd, hogy nem jó
ne mondd, hogy nem jó
Ne mondd, hogy Haskell
Haskell!
a Nok halmaza megszamlalhato. absztrahaljunk egy kicsit, tegyuk fel hogy vegtelen sok No van (ez vegulis nem lenne katasztrofa), es soroljuk fel oket :
nok = [1..]
alkalmazzuk ra a "love" operatort a Nokre:
map (<3) nok
az eredmeny ekvivalens ezzel:
[True,True] ++ repeat False
konkluzio: hiaba van vegtelen sok No, csak az elso kettonel van eselyunk - utana nem marad mas nekunk, csak a Haskell...
Post a Comment