Haskell | |
---|---|
Nyelvóra | funkcionális , lusta , moduláris |
A végrehajtás típusa | összeállította , értelmezte |
Megjelent | 1990 |
Szerző | Augustsson, Lennart [d] , Warren Burton [d] , Kevin Hammond [d] , Hudak, Paul [d] ,John Hughes ,Thomas Jonsson ,Peyton-Jones, Simon, John Launchbury [d] .Meyer, Eric , Alastair Reil [d] és Wadler, Philip [d] |
Fejlesztő | Hudak, Paul [d] [1], Augustsson, Lennart [d] [2],John Hughes [3],Peyton-Jones, Simon[4],Meyer, Eric [4]és Wadler, Fülöp [d] [4] |
Fájlkiterjesztés _ | .hsvagy.lhs |
Kiadás | Haskell 2010 (2010. július ) |
Teszt verzió | Haskell 2020 [5] |
Típusrendszer | teljes erős statikus típuskövetkeztetéssel |
Főbb megvalósítások | GHC , HUGS , NHC , YHC |
Dialektusok |
Hélium, Gofer , O'Haskell, Haskell++, Mondrian, Disciple |
Befolyásolva |
ML és Standard ML , Lazy ML , Miranda , Lisp and Scheme , ISWIM , FP , APL , Hope and Hope+ , SISAL , Orwell , Id |
befolyásolta | Agda , Bluespec , Clojure , C# , Cat , Cayenne , Clean , Curry , Epigram , Escher , F# , Factor , Idris , Isabelle , Java Generics , LINQ , Mercury , Ωmega , Python , Qi , Raku , Rust , Scala , Swift , Timber , Visual Basic 9.0 |
Weboldal | haskell.org |
OS | Microsoft Windows és Unix-szerű operációs rendszer |
Médiafájlok a Wikimedia Commons oldalon |
A Haskell ( IPA : [ h æ s k ə l ]) egy általános célú szabványosított, tisztán funkcionális programozási nyelv . Ez az egyik leggyakoribb programozási nyelv, amely támogatja a lusta értékelést . A típusrendszer teljes , erős , statikus , automatikus típuskövetkeztetéssel , a Hindley-Milner típusrendszeren alapul . Mivel a nyelv funkcionális, a fő vezérlőstruktúra egy függvény .
A nyelv megkülönböztető vonása a gépeléshez való komoly hozzáállás; sok tekintetben ezzel összefüggésben a nyelv a típuselmélet kutatójáról és a kombinatorikus logika feltalálójáról , Haskell Curryről kapta a nevét .
Vannak más programozási nyelvek kóddal való interakciós eszközei. Van beépített támogatás a többfeladatos és párhuzamos programozáshoz, fejlett eszközök (automatikus tesztelési , hibakeresési és profilalkotási eszközök , beleértve a párhuzamos programokat is), több ezer nyílt forráskódú könyvtár létezik .
A Haskell az ML nyelvek családjába tartozik . Közvetlen hatással volt rá a Miranda nyelv , amelyet 1985-ben David Turner fejlesztett ki . A Miranda volt az első tisztán funkcionális nyelv, amely kereskedelmi támogatást kapott, és viszonylag népszerű volt az 1980-as években, de továbbra is védett szoftver maradt . Ez megnehezítette a lusta funkcionális programozás lehetőségeinek fejlesztését és feltárását, így néhány év alatt több mint egy tucat hasonló nyelv jelent meg. A különböző fejlesztők erőfeszítéseinek egyesítése érdekében 1987-ben az oregoni Funkcionális Programozási Nyelvek és Számítógépes Architektúra Konferencián (FPCA'87) úgy döntöttek, hogy létrehoznak egy bizottságot egy nyílt szabvány kidolgozására .
1990-ben javasolták a nyelv első verzióját, a Haskell 1.0-t. Később a bizottság munkája tovább folytatódott, és 1999-ben megjelent a The Haskell 98 Report [6] , amely hosszú évekre stabil nyelvi standardtá vált. A nyelv azonban továbbra is gyorsan fejlődött, és a GHC fordító volt az új funkciók de facto szabványa.
A nyelv új verzióinak fejlesztése nyitott, ezt a folyamatot Haskell-nek [7] (Haskell Prime [ˈhæskəl praɪm], "Haskell stroke") hívják. Mindenki megvitatásra terjesztheti elő javaslatait, a javaslatokat egész évben megvitatják, a bizottság kiválasztja és kihirdeti az elfogadásra kész javaslatokat, új bizottság alakul, és az év végéig készül a nyelv új változata. év. Így mostantól minden évben megjelenhetnek a nyelv új verziói. A tervek szerint egyes revíziókat „jelentősnek” nyilvánítanak, és hosszú ideig fenntartják.
A Haskell 2010-et 2009 végén jelentették be [8] , de a Haskell 98 továbbra is az utolsó "jelentős" verzió (szabvány).
A Haskell nyelv főbb jellemzői a következők:
Sok idő telt el az utolsó nyelvi szabvány (Haskell98) elfogadása óta, és azóta a nyelv vezető implementációi (ghc és hugs) számos további funkcióval bővültek:
A Haskell nyelvnek számos megvalósítása létezik [10] . Egyes megvalósítások a gyakorlati alkalmazásokra összpontosítanak, míg mások elsősorban tudományos érdeklődésre tartanak számot.
A gyakorlatban a legnépszerűbb [11] a GHC optimalizáló fordító , amely gyors kódot készít, és számos nyelvi kiterjesztés használatát teszi lehetővé. A GHC képes optimalizálni a programok sebességét és tömörségét egyaránt, valamint képes többfeladatos és párhuzamos kód létrehozására. A GHC fordítóhoz a GHCi interaktív programozási környezet is tartozik, beépített hibakeresővel. A GHC Windowson, MacOS X-en és számos Unix-szerű platformon (Linux, *BSD, Solaris) fut. A GHC a szabványos fordító a Haskell Platformban, és ezen az első helyen tesztelik az összes új könyvtárat [12] .
Egy másik népszerű nyelvi megvalósítás a HUGS tolmács . C nyelven íródott, kis terjesztési méretű és szinte minden platformon működik. A HUGS interaktív programozási környezetet biztosít, de Haskell programokat is futtathat szkriptnyelvek stílusában . A Windows felhasználók használhatják a WinHugs grafikus interaktív környezetet. Mivel a HUGS egy tolmács, a benne futó programok lassabban futnak, mint a legtöbb Haskell fordító által előállított kód. A HUGS-t gyakran ajánlják nyelvtanulási médiumként. A HUGS teljes mértékben támogatja a Haskell 98 nyelvi szabványt, valamint néhány népszerűbb nyelvi bővítményt.
Egyéb figyelemre méltó megvalósítások [13] :
2009-ben született meg a Haskell Platform [14] koncepciója – egy szabványos nyelvi disztribúciós készlet, amely a fordítóprogramon (GHC) kívül további eszközöket (a Cabal csomag építési és telepítési rendszerét) és népszerű könyvtárakat is tartalmaz. .
A Haskell Platform mostantól a fejlesztők számára ajánlott alapdisztribúció. A Haskell Platform kész buildjei elérhetők Windows, MacOS X és számos Linux disztribúció számára.
A legtöbb Haskell fordító natív kódot állít elő az alapul szolgáló platformhoz, de számos projekt is lehetővé teszi kód előállítását virtuális gépekhez , vagy kód létrehozását más programozási nyelveken. Az ilyen projektek érettségi foka és támogatási szintje nagyon eltérő.
Az YHC fordító használatakor több érdekes célplatform is elérhető, mint például a Python YHC bájtkód értelmezője és az YHC bytecode to Erlang Core konverter, de ezek a fejlesztések még csak kísérletiek. A nyelv részhalmazainak megvalósításai is vannak különböző célplatformokon.
Nyelvi megvalósítási bővítmények (a GHC-re vonatkozik):
A következő példa a Haskell nyelv szintaxisát mutatja be a faktoriális kiszámítására szolgáló függvény implementálásakor :
fac :: Integer -> Integer fac 0 = 1 fac n | n > 0 = n * fac ( n - 1 )Ez a meghatározás leírja a faktoriális mint rekurzív függvény kiszámításának folyamatát . Ez a meghatározás hasonló a számítástechnikai tankönyvekben található definícióhoz . A legtöbb Haskell forráskód szintaxisát és használatát tekintve hasonló a matematikai jelölésekhez, például a fenti példa átírható így
fac n = termék [ 1 .. n ]ami megfelel a faktoriális matematikai definíciójának.
A fenti kód első sora nem kötelező, és egy függvénytípus -deklaráció , azaz megadja az argumentumtípusokat (az utolsó " ->" előtt megadva) és a visszatérési típust (az utolsó " ->" után van megadva). Ez a sor a következőképpen olvasható: a függvény factípusa ( ::) egésztől egész számig ( Integer -> Integer) . Ez azt jelenti, hogy egy egész argumentumot vesz fel bemenetként (a "->" bal oldalára írva), és egy egész típusú eredményt ad vissza (a "->" jobb oldalára írva). Ha a programozó nem adta meg kifejezetten a típusokat, a fordító vagy az értelmező automatikusan meghatározhatja azokat.
A második és harmadik sor alkotja a függvénytest definícióját. A definíció mondatokból, vagy "záradékokból" ( angol záradék ) áll. Minden mondat egy minta-kifejezés pár. A fordító vagy az értelmező a mintaillesztési mechanizmust használja az egyik kifejezés kiválasztásához. Ebben az esetben a definíció második sora lesz kiválasztva, ha a függvényhívás aktuális paramétere facnulla.
A harmadik sorban a mintaillesztési mechanizmuson kívül egy őr kifejezést használunk - n > 0. Garantálja, hogy a függvény nem fog működni olyan negatív számoknál, amelyekhez nincs definiálva a faktoriális. Ha negatív számot adunk át tényleges paraméterként a függvénynek fac, akkor a program egy hibaüzenettel leáll.
A fordított lengyel jelölésű kifejezések kiértékelésére szolgáló legegyszerűbb számológép a Haskellben definiálható egyetlen funkcióval:
calc :: String -> Float calc = fej . foldl f [] . szavak ahol f :: [ Float ] -> String -> [ Float ] f ( x : y : zs ) "+" = ( y + x ) : zs f ( x : y : zs ) "-" = ( y - x ) : zs f ( x : y : zs ) "*" = ( y * x ) : zs f ( x : y : zs ) "/" = ( y / x ) : zs f ( x : y : zs ) "FLIP" = y : x : zs f ( x : zs ) "ABS" = ( abs x ) : zs f xs y = beolvasott y : xsAz itt szereplő bemeneti kifejezést tartalmazó beviteli karakterláncot a szabványos függvény egy szólistára wordsbontja - szóköz karakterek közötti karakterláncokra -, amelyet a bal oldali hajtás funkció ( foldl) dolgoz fel balról jobbra, egy-egy szót a függvény segítségével. f, amely az olvasott számok és köztes értékek munkalistáját tartja karban (először [] egy üres lista), és minden bemeneti szót egy aritmetikai függvény szimbólumaként vagy számként értelmez, amikor kiértékeli a kifejezés végső értékét ( amely az első megmaradt érték lesz a munkalistában, amikor a bemeneti kifejezés szólistája befejeződik, így onnan a szabványos függvény segítségével lekérhető head).
Itt (.)van a függvényösszetétel operátor, (f . g) x = f (g x). Például,
* Fő > "1 2 3 + 4 * - ABS" számítás 19.0Egy másik példa a Fibonacci-számok végtelen listájának lineáris időben történő kiszámításának módját mutatja be:
szálak = 0 : 1 : cipzár ( + ) szálakkal ( farokszálak ) _A végtelen lista itt a magkurziós mechanizmussal van definiálva - a lista további értékei az előzőek alapján vannak beállítva, a lista kezdeti 0és 1első két elemével, valamint egy generátor zipWith (+) fibs (tail fibs) kifejezéssel , amely minden elemet kiszámít . az előző kettő alapján a harmadiktól kezdve egy szabványos függvényen keresztül, amely zipWith (+)két bemeneti listája elemeit párosítja.
Ez a meghatározás a lusta értékelés példája , amely a Haskell nyelv lényeges része. A definíció működésének megértéséhez fontolja meg az első hét Fibonacci-szám kiszámítását a segítségével:
fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ... + + + + + + farokszálak = 1 : 1 : 2 : 3 : 5 : 8 : ... ====== zip (+) = 1 : 2 : 3 : 5 : 8 : ... fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ...Ugyanez írható a lista-leírók használatakor is ,
fibs = 0 : 1 : [ a + b | ( a , b ) <- zip fibs ( tail fibs )]vagy a Haskell nyelv kiterjesztése a GHC ( párhuzamos listamegértések ) fordítójában :
fibs = 0 : 1 : [ a + b | a <- fibs | b < - farokszálak ]vagy közvetlenül önreferencia generáló funkcióval :
fibs = 0 : 1 : következő fibs ahol a következő ( a : t @ ( b : _ )) = ( a + b ) : következő tEzek a példák bemutatják, hogyan használhatók a listakifejezések ( listamegértések ). Az összes prímszám megtalálásának megvalósítása a szokásos módon (az egyes számok prímságának ellenőrzése ):
-- általános definíció (minden természetes szám > 1, amely prímszám) prímSzámok = 2 : [ n | n <- [ 3 .. ], isPrime n ] -- Egy szám prím, ha nincs (prím) osztója isPrime n = foldr ( \ p r -> p * p > n || ( rem n p /= 0 && r )) Igaz prímSzámokvagy Eratosthenes szitával, prototipikus, nem hatékony változatban,
prímszámok = ( térképfej . scanl mínusz [ 2 .. ] . térkép ( \ p - > [ p , p + p .. ])) prímekvagy hatékonyan, az összetett számok előzőleg lépcsőzetes folyamaival:
prímszámok = 2 : _Y (( 3 : ) . mínusz [ 5 , 7 .. ] . unionAll . map ( \ p -> [ p * p , p * p + 2 * p .. ])) ahol _Y g = g ( _Y g ) unionAll (( x : xs ) : t ) = x : unió xs ( unionAll ( pairs ) ) pairs (( x : xs ) : ys : t ) = ( x : unió xs ys ) : párok tvagy szegmensenként, tömbökönként,
import Data.Array import Data.List ( farok , inits ) ps = 2 : [ n | ( r : q : _ , px ) <- ( zip . tails . ( 2 : ) . térkép ( ^ 2 )) ps ( inits ps ), ( n , igaz ) <- assocs ( accumArray ( \ _ _ -> False ) ) Igaz ( r + 1 , q - 1 ) [ ( m , ( ) ) | p <- px , legyen s = div ( r + p ) p * p , m < - [ s , s + p .. q - 1 ]] )]kanonikus függvények használatával minus, union[27] ):
unió ( x : xs ) ( y : ys ) = LT - > x x y eset összehasonlítása _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ a b = a ++ b mínusz ( x : xs ) ( y : ys ) = LT x y eseteinek összehasonlítása - > x : mínusz xs ( y : ys ) EQ -> mínusz xs ys GT -> mínusz ( x : xs ) ) ys mínusz a b = aEgy egyszerű példa algebrai adattípusok használatára a játékkártyák leírására. A típusazonosítók nagybetűkkel kezdődnek. Változók és függvények azonosítói - kisbetűről. Az új algebrai típusokat a kulcsszó határozza meg data. A típusszinonimákat a kulcsszó határozza meg type.
-- Algebrai típusösszeg Suit ("felsorolás"). -- A ruha típusú érték lehet a jobb oldalon felsoroltak egyike -- (vagy pikk, vagy ütő, vagy gyémánt vagy szív). -- A "Suit" itt a _type_, -- és a "Spades", "Clubs" stb. konstruktoraként működik. - _data_ konstruktorok. adatok Öltöny = Spades | Klubok | Tamburinok | Hearts -- opcionális automatikus következtetés az osztálypéldányokról -- amely lehetővé teszi az értékek karakterláncokká konvertálását (a Show függvény segítségével) és vissza (a Read funkció olvasási funkciójával), valamint összehasonlítását egymással -- (az Eq és Ord osztályok függvényei szerint). származtatás ( Show , Read , Eq , Ord ) -- Algebrai összeg típusa Érték adatok Érték = Hét | Nyolc | Kilenc | Tíz | Jack | hölgy | Király | Ász származtatás ( Show , Read , Eq , Ord ) -- Algebrai típus-termék térkép ("type-tuple"). -- A Card típusú értékek Value és Suit típusú értékek kombinációi, -- ezeket a K adatkonstruktor egyesíti. -- Az adatkonstruktor és a típuskonstruktor neve gyakran megegyezik. adatkártya = K érték öltöny származtatása ( Show , Read , Eq , Ord ) _ -- A Térkép típusú értékek listájának szinonimája. típus Kéz = [ Kártya ] -- Függvény, amely meghatározza, hogy van-e házasság (ugyanazon színű király és királynő) a kézben. isMarriage :: Hand -> Bool isMarriage of the card = -- csak keresse meg legalább egy öltöny házasságát bármelyik ( isMarriageSuits ) [ Spades , Clubs , Diamonds , Hearts ] ahol -- ellenőrizze, hogy van-e dáma és király is az adott öltöny m a kézben vanMariageSuits m = ( K Queen m ) ` elem` kártyák && ( K King m ) ` elem` kártyák _ _ -- kézi példák hand = [ K Ütőkirálynő , K Szívek Hét Királya , K Gyémántok ász ] Hand_without_marriage = [ K Páktíz , K Pák király , K Szívek királynője ] _ _ _ main = do check hand check hand_without_marriage check [] -- üres eloszlás ahol check kk = putStrLn ( ( mutat kk ) ++ " -> " ++ ( show ( Margage kk )) ) -- Konklúzió: -- [A ütők királynőjéhez, a szívek hétéhez, a ütők királyához, a gyémántok ászához] -> igaz -- [a pikkek tízéhez, a pikk királyhoz, a a szívek királynője] -> Hamis -- [] -> HamisNumerikus integráció trapéz módszerrel:
trapézIntegrálása f a b n = (( összeg $ térkép f [ a + h , a + 2 * h .. b - h ]) + t ) * h ahol t = ( f a + f b ) / 2 h = ( b ) -a ) / n _ fő = nem nyomtat $ trapezeIntegrate ( \ x -> x * sin x ) 0 ( 2 * pi ) 100 -- Kimenet: -6.281118086046067Az alábbi példa bemutatja, hogyan kell dolgozni Unicode karakterláncokkal .
import Data.Char ( toLower , isAlpha ) palindrom :: [ Char ] -> Bool palindrom s = norma == fordított norma ahol norma = leképezés az alsó $ szűrő isAlpha $ s teszt :: [ Char ] -> IO () teszt s = putStrLn $ s ++ ": " ++ show ( palindrom s ) fő = teszt elvégzése " És kék a Jeniszejben" teszt "Rózsa esett Azor mancsára" teszt "Nem egy rózsa esett Azor mancsára" teszt "A világ olyan, mint Róma" teszt "A világ nem Róma" teszt "Inkább Pi" teszt "حوت فمه مفتوح" teszt "Ne mateno, bone tamen" -- Következtetés: -- És a Jenyiszejben — kék: igaz -- Rózsa esett Azor mancsára: igaz -- Egy rózsa sem esett Azor mancsára: hamis -- A világ olyan, mint Róma: igaz -- A világ nem Róma: Hamis -- Inkább Pi: Igaz -- حوت فمه مفتوح: Igaz -- Ne mateno, csont tamen: igazHaskell egyre inkább[ float ] kereskedelmi környezetben használatos [28] . Ezt elősegíti a közösségben elfogadott hagyomány, hogy a könyvtárakat liberális licencek alatt adják ki (a szabadon elérhető könyvtárak több mint 70%-a BSD, MIT licencek alapján kerül terjesztésre, vagy nyilvánosan hozzáférhető).
Íme néhány példa a Haskell nyelven írt kereskedelmi alkalmazásokra: A Bluespec SystemVerilog, egy beágyazható félvezető-tervező és -ellenőrző nyelv, a Haskell nyelv kiterjesztése [29] . A Cryptol, a kriptográfiai algoritmusok fejlesztésére és ellenőrzésére szolgáló kereskedelmi nyelv, a Haskellben van megvalósítva. Nevezetesen, hogy az első hivatalosan ellenőrzött seL4 mikrokernelt is Haskellben írták.
A Haskellt aktívan használják a pénzügyi programozás, kockázatelemzés, döntéstámogató rendszerek területén . A Haskellt a városi tájgenerátor fejlesztői használják játékokhoz és szimulációkhoz, Gamr7 [30] . Vannak példák a nyelv sikeres alkalmazására magáninformációs rendszerek fejlesztésére kereskedelmi szervezetekben (beleértve a FÁK-országokat is) [31] . Az analitikus DBMS SQreamDB SQL elemző modul Haskell nyelven van írva.
A Haskellben írt nyílt forráskódú könyvtárak és alkalmazások jelentős része elérhető a Hackage archívumban. Ezek közé tartozik a Pandoc univerzális jelölőkonvertáló , a Yi emacs-szerű szövegszerkesztő és a Leksah integrált fejlesztői környezet . A rendszerfejlesztések között szerepel a Darcs elosztott verziókezelő rendszer, a House operációs rendszer és az Xmonad csempézett ablakkezelő .
A GHC fordító gyakran tesztterületként szolgál új funkcionális programozási és optimalizálási funkciók teszteléséhez. Ezzel egy időben az Agda , Curry , Epigram nyelvi fordítók , valamint a Perl 6 nyelvű Pugs első fordítója és értelmezője (alig egy hónap alatt készült el) Haskellben íródott .
Haskell fordítók | |
---|---|
Tolmácsok |
|
Fordítók |
Programozási nyelvek | |
---|---|
|