Haskell | |
---|---|
Språkklass | funktionell , lat , modulär |
Utförandetyp | sammanställt , tolkat |
Framträdde i | 1990 |
Författare | 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] och Wadler, Philip [d] |
Utvecklaren | Hudak, Paul [d] [1], Augustsson, Lennart [d] [2],John Hughes [3],Peyton-Jones, Simon[4],Meyer, Eric [4]och Wadler, Philip [d] [4] |
Filtillägg _ | .hseller.lhs |
Släpp | Haskell 2010 (juli 2010 ) |
Testversion | Haskell 2020 [5] |
Typ system | full stark statisk med typinferens |
Stora implementeringar | GHC , KRAM , NHC , YHC |
Dialekter |
Helium, Gofer , O'Haskell, Haskell++, Mondrian, Lärjunge |
Blivit påverkad |
ML och Standard ML , Lazy ML , Miranda , Lisp and Scheme , ISWIM , FP , APL , Hope and Hope+ , SISAL , Orwell , Id |
påverkas | 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 |
Hemsida | haskel.org |
OS | Microsoft Windows och Unix-liknande operativsystem |
Mediafiler på Wikimedia Commons |
Haskell ( IPA : [ h æ s k ə l ]) är ett standardiserat rent funktionellt programmeringsspråk för allmänna ändamål . Det är ett av de vanligaste programmeringsspråken med stöd för lat utvärdering . Typsystemet är komplett , starkt , statiskt , med automatisk typinferens , baserat på Hindley-Milner-systemet . Eftersom språket är funktionellt är huvudkontrollstrukturen en funktion .
Ett utmärkande drag för språket är en seriös inställning till maskinskrivning; i många avseenden i samband med detta är språket uppkallat efter forskaren inom typteori och uppfinnaren av kombinatorisk logik Haskell Curry .
Det finns sätt att interagera med kod i andra programmeringsspråk. Det finns inbyggt stöd för multitasking och parallell programmering, avancerade verktyg (verktyg för automatisk testning , felsökning och profilering , inklusive för parallella program), det finns flera tusen bibliotek med öppen källkod .
Haskell tillhör ML- familjen av språk . Han var direkt influerad av Miranda- språket , utvecklat 1985 av David Turner . Miranda var det första rena funktionella språket som hade kommersiellt stöd och var relativt populärt på 1980-talet, men förblev proprietär programvara . Detta gjorde det svårt att utveckla och utforska möjligheterna med lat funktionell programmering, så på bara ett par år dök mer än ett dussin liknande språk upp. För att förena ansträngningarna från olika utvecklare 1987 vid konferensen om funktionella programmeringsspråk och datorarkitektur i Oregon (FPCA'87), beslutades det att skapa en kommitté för att utveckla en öppen standard .
1990 föreslogs den första versionen av språket, Haskell 1.0. Senare fortsatte kommitténs arbete och 1999 publicerades Haskell 98-rapporten [6] , som blev en stabil språkstandard under många år. Språket fortsatte dock att utvecklas snabbt, med GHC- kompilatorn som de facto standard för nya funktioner.
Utvecklingen av nya versioner av språket är öppen, denna process kallas Haskell' [7] (Haskell Prime [ˈhæskəl praɪm], "Haskell stroke"). Alla kan lägga fram sina förslag för diskussion, förslag diskuteras under hela året, kommittén väljer ut och tillkännager förslag som den är redo att acceptera, en ny kommitté bildas och en ny version av språket förbereds i slutet av år. Således kan nya versioner av språket nu dyka upp varje år. Det är planerat att deklarera vissa revisioner som "stora" och att behålla sådana revisioner under lång tid.
Haskell 2010 tillkännagavs i slutet av 2009 [8] , men Haskell 98 är fortfarande den sista "betydande" versionen (standard).
De huvudsakliga egenskaperna hos Haskell-språket är följande:
Mycket tid har gått sedan antagandet av den senaste språkstandarden (Haskell98), och sedan dess har de ledande implementeringarna av språket (ghc och kramar) utökats med många ytterligare funktioner:
Det finns flera implementeringar av Haskell-språket [10] . Vissa implementeringar är fokuserade på praktiska tillämpningar, medan andra är främst av akademiskt intresse.
Den mest populära [11] i praktiken är den optimerande kompilatorn GHC , som skapar snabb kod och tillåter användning av många språktillägg. GHC kan optimera både hastighet och kompakthet hos program, och kan skapa multitasking och parallelliserad kod. GHC-kompilatorn kommer också med den interaktiva GHCi-programmeringsmiljön med en inbyggd debugger. GHC körs på Windows, MacOS X och flera Unix-liknande plattformar (Linux, *BSD, Solaris). Det är GHC som är standardkompilatorn i Haskell-plattformen, och det är på den som alla nya bibliotek testas i första hand [12] .
En annan populär språkimplementering är HUGS- tolken . Den är skriven i C , har en liten distributionsstorlek och fungerar på nästan alla plattformar. HUGS tillhandahåller en interaktiv programmeringsmiljö, men kan även köra Haskell-program i stil med skriptspråk . Windows-användare kan använda WinHugs grafiska interaktiva miljö. Eftersom HUGS är en tolk, kör program som körs i den långsammare än koden som produceras av de flesta Haskell-kompilatorer. HUGS rekommenderas ofta som ett medium för språkinlärning. HUGS har fullt stöd för språkstandarden Haskell 98, såväl som några av de mer populära språktilläggen.
Andra anmärkningsvärda implementeringar [13] :
2009 bildades konceptet för Haskell-plattformen [14] - ett standardspråkdistributionspaket som förutom kompilatorn (GHC), även innehåller ytterligare verktyg (bygg- och distributionssystemet för Cabal-paketet) och en uppsättning populära bibliotek .
Haskell Platform är nu den rekommenderade basdistributionen för utvecklare. Färdiga versioner av Haskell Platform är tillgängliga för Windows, MacOS X och ett antal Linux-distributioner.
De flesta Haskell-kompilatorer producerar inbyggd kod för den underliggande plattformen, men det finns flera projekt som låter dig producera kod för virtuella maskiner eller generera kod på andra programmeringsspråk. Graden av mognad och stödnivå för sådana projekt varierar mycket.
Flera intressanta målplattformar är tillgängliga när du använder YHC-kompilatorn, såsom YHC-bytecode-tolken i Python och YHC-bytecode to Erlang Core-omvandlaren, men dessa utvecklingar är fortfarande experimentella. Det finns också implementeringar av delmängder av språket på olika målplattformar.
Språkimplementeringstillägg (gäller GHC):
Följande exempel visar syntaxen för Haskell-språket vid implementering av en funktion för att beräkna faktorial :
fac :: Heltal -> Heltal fac 0 = 1 fac n | n > 0 = n * fac ( n - 1 )Denna definition beskriver processen att beräkna faktorial som en rekursiv funktion . Denna definition liknar den som finns i läroböcker i datavetenskap . De flesta Haskell källkoder liknar matematisk notation när det gäller syntax och användning, exemplet ovan kan till exempel skrivas om som
fac n = produkt [ 1 .. n ]vilket motsvarar den matematiska definitionen av faktoriell.
Den första raden i ovanstående kod är valfri och är en funktionstypdeklaration , det vill säga den specificerar argumenttyperna (anges före den sista " ->") och returtypen (anges efter den sista " ->"). Denna rad kan läsas som: funktion fachar typ ( ::) från heltal till heltal ( Integer -> Integer) . Detta betyder att det tar ett heltalsargument som indata (skrivet till vänster om "->") och returnerar ett resultat av heltalstyp (skrivet till höger om "->"). Om programmeraren inte har specificerat typerna explicit, kan kompilatorn eller tolken bestämma dem automatiskt.
Den andra och tredje raden utgör definitionen av funktionskroppen. Definitionen består av meningar, eller "klausul" ( engelska klausul ). Varje mening är ett mönster-uttryckspar. Kompilatorn eller tolken använder mönstermatchningsmekanismen för att välja ett av uttrycken. I detta fall kommer den andra raden i definitionen att väljas när den faktiska parametern för funktionsanropet facär noll.
På den tredje raden används, förutom mönstermatchningsmekanismen, ett skyddsuttryck - n > 0. Det garanterar att funktionen inte kommer att fungera för negativa tal, för vilka faktorn inte är definierad. Om ett negativt tal skickas som en faktisk parameter till funktionen fackommer programmet att stoppas med ett felmeddelande.
Den enklaste räknaren för att utvärdera uttryck i omvänd polsk notation kan definieras i Haskell med en enda funktion:
calc :: String -> Float calc = huvud . foldl f [] . ord där 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 = läs y : xsInmatningssträngen med inmatningsuttrycket här delas av standardfunktionen wordsi en lista med ord - strängar mellan blanksteg - som bearbetas av den vänstra vikningsfunktionen ( foldl) från vänster till höger, ett ord i taget med funktionen f, som upprätthåller en arbetslista med lästa siffror och mellanvärden (först [] - en tom lista) och tolkar varje inmatningsord som en symbol för en aritmetisk funktion eller som ett tal när det utvärderar uttryckets slutvärde ( vilket blir det första kvarvarande värdet i arbetslistan när inmatningsuttryckets ordlista är klar, så att den kan hämtas därifrån med standardfunktionen head).
Här (.)är funktionssammansättningsoperatorn, (f . g) x = f (g x). Till exempel,
* Main > beräkna "1 2 3 + 4 * - ABS" 19,0Ett annat exempel visar ett sätt att beräkna en oändlig lista med Fibonacci-tal i linjär tid:
fibs = 0 : 1 : zipMed ( + ) fibs ( svansfiber ) _Den oändliga listan här definieras med hjälp av corecursion- mekanismen - listans efterföljande värden ställs in baserat på de föregående, med de initiala 0och 1som de två första elementen i listan, och ett generatoruttryck zipWith (+) fibs (tail fibs) som beräknar alla element med början från den tredje baserat på de två föregående, genom en standardfunktion zipWith (+)som summerar element i par av två av dess inmatningslistor.
Den här definitionen är ett exempel på lat utvärdering , som är en viktig del av Haskell-språket. För att förstå hur denna definition fungerar kan du överväga att beräkna de första sju Fibonacci-talen med hjälp av den:
fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ... + + + + + + svansfiber = 1 : 1 : 2 : 3 : 5 : 8 : ... ====== zipMed (+) = 1 : 2 : 3 : 5 : 8 : ... fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ...Detsamma kan skrivas även när man använder listspecifikationer ,
fibs = 0 : 1 : [ a + b | ( a , b ) <- zip fibs ( svansfiber ) ]eller en förlängning av Haskell-språket implementerat i GHC-kompilatorn ( Parallell List Comprehensions ) :
fibs = 0 : 1 : [ a + b | a <- fibs | b < - svansfiber ]eller med en direkt självreferensgenererande funktion :
fibs = 0 : 1 : nästa fibs där nästa ( a : t @ ( b : _ )) = ( a + b ) : nästa tDessa exempel visar hur listuttryck ( listuppfattningar ) kan användas. Implementeringen av att hitta alla primtal på vanligt sätt ( kontrollera varje nummer för primitet ):
-- allmän definition (alla naturliga tal > 1 som är primtal) primeNums = 2 : [ n | n <- [ 3 .. ], är Prime n ] -- Ett tal är primtal om det inte har några (primtal) divisorer isPrimtal n = foldr ( \ p r -> p * p > n || ( rem n p /= 0 && r )) Sanna primtaleller med sikten från Eratosthenes , i en prototypisk, ineffektiv variant,
primtal = ( karthuvud . scanl minus [ 2 .. ] . map ( \ p -> [ p , p + p .. ] )) primtaleller effektivt, med strömmarna av sammansatta tal som tidigare var kaskad:
primtal = 2 : _Y (( 3 : ) . minus [ 5 , 7 .. ] . unionAll . map ( \ p -> [ p * p , p * p + 2 * p .. ])) där _Y g = g ( _Y g ) unionAll (( x : xs ) : t ) = x : union xs ( unionAll ( par t )) par (( x : xs ) : ys : t ) = ( x : union xs ys ) : par teller segment för segment, efter matriser,
import Data.Array import Data.List ( svansar , inits ) ps = 2 : [ n | ( r : q : _ , px ) <- ( zip . tails . ( 2 : ) . map ( ^ 2 )) ps ( inits ps ), ( n , True ) <- assocs ( accumArray ( \ _ _ -> False ) Sant ( r + 1 , q - 1 ) [ ( m , ( ) ) | p <- px , låt s = div ( r + p ) p * p , m < - [ s , s + p .. q - 1 ]] )]använder kanoniska funktioner minus, union[27] ):
union ( x : xs ) ( y : ys ) = fall jämför x y av LT -> x : union xs ( y : ys ) EQ -> x : union xs ys GT -> y : union ( x : xs ) ys union a b = a ++ b minus ( x : xs ) ( y : ys ) = falljämförelse x y av LT -> x : minus xs ( y : ys ) EQ - > minus xs ys GT -> minus ( x : xs ) ) ys minus a b = aEtt enkelt exempel på att använda algebraiska datatyper för att beskriva spelkort. Typidentifierare börjar med versaler. Identifierare av variabler och funktioner - från gemener. Nya algebraiska typer definieras av nyckelordet data. Typsynonymer definieras av nyckelordet type.
-- Algebraisk typ-summa färg ("uppräkning"). -- Ett värde av färgtypen kan vara ett av de som listas till höger -- (eller spader, eller klöver, eller ruter eller hjärter). -- "Suit" fungerar här som en konstruktör av _type_, -- och "Spades", "Clubs", etc. - _data_ konstruktörer. data Färg = Spader | Klubbar | Tamburiner | Hearts -- valfri automatisk slutledning av klassinstanser -- som låter dig konvertera värden till strängar (med hjälp av showfunktionen från Show) -- och tillbaka (med läsfunktionen från Read), samt jämföra dem med varandra -- (genom funktioner för klasserna Eq och Ord). härleda ( Visa , Läs , Ekv , Ord ) -- Algebraisk summatyp Värdedata Värde = Sju | Åtta | Nio | Tio | Jack | dam | kung | Ess -derivering ( Visa , Läs , Ekv , Ord ) -- Algebraisk typ-produktkarta ("typ-tuppel"). -- Värden av typen Kort är kombinationer av värden av typerna Value och Suit, -- förenade av datakonstruktören K. -- Ofta är namnen på datakonstruktören och typkonstruktören desamma. datakort = K Value Suit - derivering ( Show , Read , Eq , Ord ) -- En synonym för en värdelista av typen Karta. typ Hand = [ Kort ] -- En funktion som avgör om det finns ett äktenskap (kung och drottning i samma färg) i handen. isMarriage :: Hand -> Bool isMarriage av kortet = - hitta bara äktenskapet av minst en färg valfri ( isMarriageSuits ) [ Spader , klöver , Ruter , Hjärter ] där -- kontrollera om det finns både en dam och en kung av den givna färgen m i handen är MariageSuits m = ( K Queen m ) ` elem`- kort && ( K King m ) ` elem`- kort _ _ -- handexempel hand = [ K Klöverdrottning , K Sju av hjärter , K Klöverkung , K Ruter ess ] hand_without_marriage = [ K Spader tio , K Spaderkung , K Hjärtadrottning ] _ _ main = kontrollera handcheck hand_without_marriage check [ ] -- tom distribution där check kk = putStrLn ( ( visa kk ) ++ " -> " ++ ( visa ( är Margage kk ) ) ) -- Slutsats: -- [Till klöverdrottningen, till hjärtans sju, till klöverkungen, till ruter-ess] -> Sant -- [Till spadertio, till spaderkungen, till hjärternas drottning] -> Falskt -- [] -> FalsktNumerisk integration med trapetsmetoden:
trapetsIntegrera f a b n = (( summa $ map f [ a + h , a + 2 * h .. b - h ]) + t ) * h där t = ( f a + f b ) / 2 h = ( b ) -a ) / n _ main = skriv ut $ trapezeIntegrate ( \ x -> x * sin x ) 0 ( 2 * pi ) 100 -- Utdata: -6,281118086046067Exemplet nedan visar hur man arbetar med Unicode- strängar .
importera Data.Char ( toLower , isAlpha ) palindrom :: [ Char ] -> Bool palindrom s = norm == omvänd norm där norm = map to Lower $ filter isAlpha $ s test :: [ Char ] -> IO () test s = putStrLn $ s ++ ": " ++ show ( palindrom s ) main = testa "Och blå i Yenisei" test "En ros föll på Azors tass" test "Inte en ros föll på Azors tass" test "Världen är som Rom" test " Världen är inte Rom" test "Jag föredrar Pi" test "حوت فمه مفتوح" test "Ne mateno, bone tamen" -- Slutsats: -- Och i Jenisej — blått: Sant -- En ros föll på Azors tass: Sant -- Inte en ros föll på Azors tass: Falskt -- Världen är som Rom: Sant -- Världen är inte Rom: Falskt -- jag föredrar Pi: Sant -- حوت فمه مفتوح: Sant -- Ne mateno, bone tamen: SantHaskell blir alltmer[ float ] används i kommersiella miljöer [28] . Detta underlättas av traditionen som antagits i samhället att släppa bibliotek under liberala licenser (mer än 70 % av de fritt tillgängliga biblioteken distribueras under villkoren för BSD, MIT-licenser eller är allmän egendom).
Här är några exempel på kommersiella tillämpningar skrivna i Haskell: Bluespec SystemVerilog, ett inbäddningsbart halvledardesign- och verifieringsspråk, är en förlängning av Haskell-språket [29] . Cryptol, ett kommersiellt språk för att utveckla och verifiera kryptografiska algoritmer, är implementerat i Haskell. Noterbart är att den första formellt verifierade seL4- mikrokärnan också skrevs i Haskell.
Haskell används aktivt inom området finansiell programmering, riskanalys, beslutsstödssystem . Haskell används av utvecklarna av stadslandskapsgeneratorn för spel och simuleringar Gamr7 [30] . Det finns exempel på framgångsrik tillämpning av språket för utveckling av privata informationssystem i kommersiella organisationer (inklusive de i OSS-länderna) [31] . I det analytiska DBMS SQreamDB skrivs SQL -parsermodulen i Haskell.
En betydande del av biblioteken och applikationerna med öppen källkod skrivna i Haskell är tillgängliga i Hackage-arkivet. Bland dem är Pandocs universella markup - omvandlare , den Yi emacs-liknande textredigeraren och den integrerade utvecklingsmiljön Leksah . Bland systemutvecklingarna finns Darcs distribuerade versionskontrollsystem, House - operativsystemet och Xmonad -kakelfönsterhanteraren .
GHC-kompilatorn fungerar ofta som en testplats för att testa nya funktionella programmerings- och optimeringsfunktioner. Samtidigt skrevs språkkompilatorerna Agda , Curry , Epigram , samt den första kompilatorn och tolken av Perl 6 -språket Mops (den skapades på bara en månad) i Haskell .
Haskell översättare | |
---|---|
Tolkar |
|
Kompilatorer |
Programmeringsspråk | |
---|---|
|