Privacy Policy Cookie Policy Terms and Conditions Haskell programozási nyelv - Wikipédia

Haskell programozási nyelv

A Wikipédiából, a szabad lexikonból.

Tartalomjegyzék

[szerkesztés] Bevezető

A Haskell tisztán funkcionális, lusta kiértékelésű, polimorf típusokat és magasabb rendű függvényeket tartalmazó programozási nyelv. A nyelv ezzel meglehetősen különbözik a ma általában használatos nyelvektől. A nyelvet Haskell Brooks Curry amerikai matematikusról kapta nevét, aki a matematikai logikában kifejtett munkássága révén hozzájárult a funkcionális nyelvek elméleti alapjainak fejlődéséhez. A Haskell nyelv alapja a lambda-kalkulus.

A nyelv tömörségét és kifejezőképességét bemutató rövid példaprogram, a gyorsrendezés megvalósítása:

gyorsRendezes []      =  []
gyorsRendezes (x:xs)  =  gyorsRendezes kisebbElemek ++ [x] ++ gyorsRendezes nemKisebbElemek
  where
    kisebbElemek     =  [y | y <- xs, y < x]
    nemKisebbElemek  =  [y | y <- xs, y >= x]

Az (rekurzív) algoritmus a következő: Ha üres a lista, akkor rendezett. Egyébként vesszük az első elemet és sorban összefűzzük a kisebb elemek rendezett listáját, az elemet tartalmazó listát, valamint a nem kisebb elemek rendezett listáját. (Itt [] az üres lista, x a paraméterként átadott lista első eleme, xs a maradék lista, ++ a lista-összefűzés operátora. Az utolsó előtti sorban a halmazjelölés-szerű listaelőállító konstrukció szerepel, jelentése: olyan y-ok listája, ahol y az xs eleme, és y kisebb mint x.)

[szerkesztés] A nyelv nagyon rövid története

A Haskell aránylag fiatal nyelv, de a gyökerei elég mélyre nyúlnak az időben. 1978-ban megjelent John Backus cikke, amelyben leírja az FP nyelvet, amely magasabb rendű függvényeket használó tiszta funkcionális nyelv volt és amely később nagy hatással volt a funkcionális nyelvek fejlődésére. Körülbelül ebben az időben az Edinburgh-i Egyetemen kifejlesztik az ML nyelvet, amelyet akkor még csak egy tételbizonyító programhoz akartak használni, de később rájöttek, hogy általános célú nyelvként is megállja a helyét. 1985-86-ban fejlesztették ki Miranda nyelvet, amelyet az 1987-ben megalakult Haskell nyelvi bizottság a Haskell alapjául akart felhasználni. A Miranda tervezőjét és jogtulajdonosát ez a lehetőség azonban nem érdekelte.

A Haskell nyelv első leírása 1990-ben jelent meg. Ez volt a Haskell 1.0. Ezután a nyelv fejlődésnek indult, és 1997-ben már az 1.4-es változatnál tartottak. 1997-ben az amszterdami Haskell Workshop alkalmával a nyelv tervezői belátták, hogy egy stabil nyelvi szabványra van szükség. 1998-ban született meg a ma is érvényben lévő Haskell 98 szabvány. Ennek javított változata 2003-ban jelent meg - ez azonban már csak kisebb korrekciókat, hibajavításokat tartalmaz.

[szerkesztés] A Haskell nyelv dióhéjban

[szerkesztés] Típusok, értékek

A Haskell erősen (szigorúan), vagy statikusan típusos nyelv. A Haskell-rendszer egy program végrehajtása előtt (pl. fordításkor) leellenőrzi a típusok helyes használatát, tehát például az 'a' + 4 kifejezést már nem fogadja el - ebben különbözik a gyengén, vagy dinamikusan típusos nyelvektől, ahol egy hasonló kifejezésnél a kiértékelése során kapunk hibajelzést.

[szerkesztés] Egyszerű, strukturált és függvénytípusok

Minden Haskell-kifejezésnek meghatározott típusa van. A nyelvben a típusok leírására típuskifejezést használunk. A kifejezések, értékek mellett feltüntethetjük azok típusát is a :: szintaktikai elem után: ez a típusjelölés.

Egész:

3 :: Integer

Karakter:

'c' :: Char

Rendezett pár:

('e', 8) :: (Char, Integer)

Rendezett hármas:

("ablak", 'A', 2)

Lista:

[1, 2, 3] :: [Integer]

A Haskellben kizárólag homogén listák vannak, tehát egy lista minden eleme ugyanolyan típusú.

Füzér:

"ceruza" :: String
['c', 'e', 'r', 'u', 'z', 'a'] :: [Char]

A két fenti kifejezés és típusaik egyenértékűek, tehát a String egyszerűen karakterek listája, tehát [Char].

Függvény:

\ x -> x + 1 :: Integer -> Integer

Ez egy olyan függvény, amelyik egyet ad a paraméteréhez (Ez tulajdonképpen egy lambda-kifejezés, ahol a \ (lejtő, vagy backslash karakter) jelöli a lambdát.) A Integer -> Integer jelölés jelentése: függvény, amelyik egész paramétert vár és egész az értéke.

[szerkesztés] Algebrai típusok

A Haskell-ben a strukturált típusok mellett algebrai típusokat is létrehozhatunk. Példa:

data Szin  =  Feher | Fekete | Kek | Sarga | Piros | Zold
data Minta  =  Kockas | Csikos | Halas | Macis

Itt a Szin azonosító egy új algebrai típust, a Feher, Fekete és a többi jobb oldalon szereplő azonosító pedig konstruktort jelöl. A konstruktorok neve nagy betűvel kezdődik. A definíció után már leírhatunk pár értéket a típusával együtt:

Fehér :: Szin
[Kek, Zold] :: [Szin]

A konstruktoroknak paramétereket is adhatunk:

data Minta  =  Kockas | Csikos | Halas | Macis
data Labda  =  SzinesLabda Szin
            |  MintasLabda Szin Minta

Ez esetben például a következő Labda típusú értékeket írhatjuk föl:

SzinesLabda Piros :: Labda
MintasLabda Feher Csikos :: Labda

[szerkesztés] Paraméteres típusok

Ez a példa egyben egy paraméteres és rekurzív típus, amellyel bináris fát ábrázolhatunk:

data Fa a  =  Level a
           |  Elagazas (Fa a) (Fa a)

Az a típusváltozó egy konkrét értéknél behelyettesítődik valamilyen (paraméter nélküli) típussal:

Level 1 :: Fa Integer
Elagazas (Level 'x') (Elagazas (Level 'y') (Level 'z')) :: Fa Char

A Fa a típuskifejezést polimorf típusnak, a Fa Integer típuskifejezést pedig a Fa a polimorf típus példányának nevezzük.

[szerkesztés] Függvények

A Haskell-ben a függvényeket egyenletek sorozatával adjuk meg. Példa:

inc :: Integer -> Integer
inc n  =  n + 1

Az első sorban megadjuk a függvény típusát egy típusjelöléssel, a második sorban pedig a magát a függvényt definiáló egyenletet. (Itt egyetlen egyenlettel adtuk meg a függvényt.)

[szerkesztés] Curry-jelölés

A Haskellben elvileg csak egyparaméteres függvények vannak. Mégis valahogy létre tudunk hozni több paraméteres függvényeket kerülő úton. Először nézzünk egy példát:

add1 :: Integer -> Integer -> Integer
add1 x y  =  x + y + 1

Az add1 függvény típusa Integer -> Integer -> Integer, ami zárójelezve így néz ki: Integer -> (Integer -> Integer) (a -> operátor jobbra köt). Ez azt jelenti, hogy az add1 függvény egy Integer paramétert vár, és egy Integer -> Integer típusú függvényt ad vissza. Az ilyen függvényeket nevezzük Curry-jelölésűnek.

Megpróbálom a fogalmat egy, a programozástól talán távolabbi példával szemléltetni. A logaritmus fogalmára úgy is gondolhatunk,

  • mint kétparaméteres függvényre: első paraméterként az alapot veszi át, és még egy számot („a keresett hatványt”), és visszadja a megfelelő értéket. Pl. a 2 és a 8 esetén 3-at.
  • De gondolhatunk a logaritmus fogalmára úgy is -- és a logab jelölés is ezt sugallja -- hogy a logaritmus egyparaméteres függvény: azonban számból nem számot, hanem függvényt állít elő. Tehát a log28 jelölés tulajdonképpen két függvényalkalmazást is magában foglal: először a log függvényt a 2 alapra alkalmazva megkapjuk a log2 függvényt, majd az (épp imént kapott) log2 függvényt a 8-ra alkalmazva megkapjuk a 3-at.

A többparaméteres függvények fogalma tehát megragadható egyparaméteres függvények alkalmazás révén is (ha megengedjük, hogy a függvények értékül függvényt adhassanak vissza).

[szerkesztés] Függvényalkalmazás

A függvényalkalmazás jele az egymás mellé írás, tehát

inc 1 => 2

(A => jel a kifejezés értékét jelöli.)

Az alkifejezéseket zárójelek közé zárjuk:

inc (inc 1) => 3

A függvényalkalmazás balra köt, tehát a fenti add1 Curry-jelölésű függvényt így használjuk:

add1 2 3 => 6

amely kifejezés tulajdonképpen ezt jelenti:

(add1 2) 3 => 6

Ebből következik, hogy az (add1 2) egyparaméteres függvény tulajdonképpen 3-at ad az Integer típusú paraméteréhez.

[szerkesztés] Esetek, minták és őrök

A strukturált adatok elemeinek szétválasztására, illetve az algebrai típusok eseteinek megkülönböztetésére a case-kifejezést használjuk.

Definiáljunk egy függvényt, amelyik összeadja a paraméterként átadott egész pár tagjait!

addpair :: (Integer, Integer) -> Integer
addpair p  =  case p of
                (x, y) -> x + y
addpair (2, 3) => 5

Írjunk egy függvényt, amelyik a Szin típusú paramétert vár, és Fekete-re 1-et, Feher-re 2-t, egyéb szín esetén 0-t ad vissza!

szinSzam :: Szin -> Integer
szinSzam szin  =  case szin of
                    Fekete -> 1
                    Feher  -> 2
                    _      -> 0

A példa magáért beszél. Az _ akármelyik értéket jelöli. A case kifejezésben a lehetőségeket sorban kell vizsgálni, tehát az _-ra csak akkor kerül sor, ha előtte nem találtunk megfelelő értéket.

Az előző két függvényt mintákkal is megírhatjuk:

addpair :: (Integer, Integer) -> Integer
addpair (x, y)  =  x + y
szinSzam :: Szin -> Integer
szinSzam Fekete  =  1
szinSzam Feher   =  2
szinSzam _       =  0

A függvény formális paramétere egy minta is lehet. A fenti két definíció jelentése pontosan megegyezik a case kifejezést használó definícióval. A paraméter helyén csak lineáris minta lehet, azaz minden változó csak egyszer szerepelhet benne (ebben különbözik a Prologtól, amelyben egy változó többször is szerepelhet a mintában).

Az esetek mellett őröket is használhatunk a függvények megadásánál:

butaPelda :: Integer -> Integer -> Integer
butaPelda x y | x > 0      =  x + y
              | otherwise  =  x * y

Ez a függvény összeadja a két paraméterét, ha x pozitív, egyébként összeszorozza.

Az őr-kifejezések mindig logikai értékűek. A Haskellben a logikai érték egy előre definiált algebrai típus:

data Bool  =  True | False

[szerkesztés] Az if-kifejezés

A más programozási nyelvekben általában szokásos if-kifejezés a Haskellben is megtalálható, pélául a butaPelda függvényünket így is megadhattuk volna:

butaPelda x y  =  if x > 0 then x + y else x * y

A Haskell-ben azonban az if-kifejezést a case-kifejezésre vezetjük vissza, az

if feltétel then igaz-ág else hamis-ág

kifejezés megfelel a

case feltétel of
  True  -> igaz-ág
  False -> hamis-ág

kifejezésnek.

THIS WEB:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2006:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu