Haskell | |
---|---|
Sprog klasse | funktionel , doven , modulær |
Udførelsestype | kompileret , fortolket |
Dukkede op i | 1990 |
Forfatter | 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] og Wadler, Philip [d] |
Udvikler | Hudak, Paul [d] [1], Augustsson, Lennart [d] [2],John Hughes [3],Peyton-Jones, Simon[4],Meyer, Eric [4]og Wadler, Philip [d] [4] |
Filtypenavn _ | .hseller.lhs |
Frigøre | Haskell 2010 (juli 2010 ) |
Test version | Haskell 2020 [5] |
Type system | fuld stærk statisk med typeslutning |
Større implementeringer | GHC , HUGS , NHC , YHC |
Dialekter |
Helium, Gofer , O'Haskell, Haskell++, Mondrian, Discipel |
Blev påvirket |
ML og Standard ML , Lazy ML , Miranda , Lisp and Scheme , ISWIM , FP , APL , Hope and Hope+ , SISAL , Orwell , Id |
påvirket | 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 |
Internet side | haskel.org |
OS | Microsoft Windows og Unix-lignende operativsystem |
Mediefiler på Wikimedia Commons |
Haskell ( IPA : [ h æ s k ə l ]) er et standardiseret rent funktionelt programmeringssprog til generelle formål . Det er et af de mest almindelige programmeringssprog med understøttelse af doven evaluering . Typesystemet er komplet , stærkt , statisk , med automatisk typeslutning baseret på Hindley-Milner-systemet . Da sproget er funktionelt, er hovedkontrolstrukturen en funktion .
Et særkende ved sproget er en seriøs holdning til maskinskrivning; i mange henseender i forbindelse hermed er sproget opkaldt efter typeteoriforskeren og opfinderen af kombinatorisk logik Haskell Curry .
Der er midler til interaktion med kode på andre programmeringssprog. Der er indbygget understøttelse af multitasking og parallel programmering, avancerede værktøjer (værktøjer til automatisk test , fejlfinding og profilering , herunder til parallelle programmer), der er flere tusinde open source-biblioteker .
Haskell tilhører ML -familien af sprog . Han var direkte påvirket af Miranda -sproget , udviklet i 1985 af David Turner . Miranda var det første rene funktionelle sprog, der havde kommerciel støtte og var relativt populært i 1980'erne, men forblev proprietær software . Dette gjorde det svært at udvikle og udforske mulighederne for doven funktionel programmering, så på blot et par år dukkede mere end et dusin lignende sprog op. For at forene indsatsen fra forskellige udviklere i 1987 på konferencen om funktionelle programmeringssprog og computerarkitektur i Oregon (FPCA'87), blev det besluttet at oprette et udvalg til at udvikle en åben standard .
I 1990 blev den første version af sproget, Haskell 1.0, foreslået. Senere fortsatte udvalgets arbejde, og i 1999 udkom Haskell 98-rapporten [6] , som blev en stabil sprogstandard i mange år. Sproget fortsatte dog med at udvikle sig hurtigt, hvor GHC- kompileren var de facto-standarden for nye funktioner.
Udviklingen af nye versioner af sproget er åben, denne proces kaldes Haskell' [7] (Haskell Prime [ˈhæskəl praɪm], "Haskell slagtilfælde"). Alle kan fremsætte deres forslag til drøftelse, forslag diskuteres i løbet af året, udvalget udvælger og annoncerer forslag, som det er klar til at acceptere, et nyt udvalg nedsættes, og en ny version af sproget er under udarbejdelse inden udgangen af år. Således kan der nu dukke nye versioner af sproget op hvert år. Det er planlagt at erklære nogle revisioner som "større" og at opretholde sådanne revisioner i lang tid.
Haskell 2010 blev annonceret i slutningen af 2009 [8] , men Haskell 98 er fortsat den sidste "betydelige" version (standard).
De vigtigste kendetegn ved Haskell-sproget er følgende:
Der er gået meget tid siden vedtagelsen af den sidste sprogstandard (Haskell98), og siden da er de førende implementeringer af sproget (ghc og kram) blevet udvidet med mange ekstra funktioner:
Der er flere implementeringer af Haskell-sproget [10] . Nogle implementeringer er fokuseret på praktiske anvendelser, mens andre primært er af akademisk interesse.
Den mest populære [11] i praksis er optimeringskompileren GHC , som skaber hurtig kode og tillader brugen af mange sprogudvidelser. GHC kan optimere både hastighed og kompakthed af programmer og er i stand til at skabe multitasking og paralleliseret kode. GHC-kompileren kommer også med det interaktive GHCi-programmeringsmiljø med en indbygget debugger. GHC kører på Windows, MacOS X og flere Unix-lignende platforme (Linux, *BSD, Solaris). Det er GHC, der er standardkompileren i Haskell Platformen, og det er på den, at alle nye biblioteker testes i første omgang [12] .
En anden populær sprogimplementering er HUGS- tolken . Den er skrevet i C , har en lille distributionsstørrelse og fungerer på næsten alle platforme. HUGS giver et interaktivt programmeringsmiljø, men kan også køre Haskell-programmer i stil med scriptsprog . Windows-brugere kan bruge WinHugs grafiske interaktive miljø. Fordi HUGS er en fortolker, kører programmer, der kører i den, langsommere end koden produceret af de fleste Haskell-kompilere. HUGS anbefales ofte som et medie til sprogindlæring. HUGS understøtter fuldt ud Haskell 98 sprogstandarden, såvel som nogle af de mere populære sprogudvidelser.
Andre bemærkelsesværdige implementeringer [13] :
I 2009 blev konceptet med Haskell-platformen [14] dannet - et standardsprogdistributionskit, der ud over compileren (GHC) også inkluderer yderligere værktøjer (Cabal-pakkeopbygnings- og implementeringssystemet) og et sæt populære biblioteker .
Haskell Platform er nu den anbefalede basisdistribution for udviklere. Klare builds af Haskell Platform er tilgængelige til Windows, MacOS X og en række Linux-distributioner.
De fleste Haskell-compilere producerer native kode til den underliggende platform, men der er flere projekter, der giver dig mulighed for at producere kode til virtuelle maskiner eller generere kode på andre programmeringssprog. Graden af modenhed og støtteniveau til sådanne projekter varierer meget.
Adskillige interessante målplatforme er tilgængelige, når du bruger YHC-kompileren, såsom YHC-bytekodefortolkeren i Python og YHC-bytekoden til Erlang Core-konverteren, men disse udviklinger er stadig eksperimentelle. Der er også implementeringer af undersæt af sproget på forskellige målplatforme.
Sprogimplementeringsudvidelser (gælder for GHC):
Følgende eksempel viser syntaksen for Haskell-sproget, når man implementerer en funktion til at beregne faktoren :
fac :: Heltal -> Heltal fac 0 = 1 fac n | n > 0 = n * fac ( n - 1 )Denne definition beskriver processen med at beregne faktorial som en rekursiv funktion . Denne definition svarer til den, der findes i lærebøger om datalogi . Det meste Haskell-kildekode ligner matematisk notation med hensyn til syntaks og brug, for eksempel kan eksemplet ovenfor omskrives som
fac n = produkt [ 1 .. n ]som svarer til den matematiske definition af faktorial.
Den første linje i ovenstående kode er valgfri og er en funktionstypedeklaration , dvs. den specificerer argumenttyperne (angivet før den sidste " ->") og returtypen (angivet efter den sidste " ->"). Denne linje kan læses som: funktion fachar type ( ::) fra heltal til heltal ( Integer -> Integer) . Dette betyder, at det tager et heltalsargument som input (skrevet til venstre for "->") og returnerer et resultat af heltalstypen (skrevet til højre for "->"). Hvis programmøren ikke har specificeret typerne eksplicit, kan compileren eller fortolkeren bestemme dem automatisk.
Den anden og tredje linje danner definitionen af funktionslegemet. Definitionen består af sætninger eller "klausul" ( engelsk klausul ). Hver sætning er et mønster-udtrykspar. Kompileren eller fortolkeren bruger mønstertilpasningsmekanismen til at vælge et af udtrykkene. I dette tilfælde vil den anden linje i definitionen blive valgt, når den aktuelle parameter for funktionskaldet facer nul.
I den tredje linje bruges der udover mønstertilpasningsmekanismen et beskyttelsesudtryk - n > 0. Det garanterer, at funktionen ikke vil fungere for negative tal, for hvilke faktoren ikke er defineret. Hvis et negativt tal sendes som en faktisk parameter til funktionen fac, stopper programmet med en fejlmeddelelse.
Den enkleste lommeregner til at evaluere udtryk i omvendt polsk notation kan defineres i Haskell med en enkelt funktion:
calc :: String -> Float calc = hoved . fold f [] . ord hvor 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 : xsIndtastningsstrengen med inputudtrykket her opdeles af standardfunktionen wordsi en liste af ord - strenge mellem blanktegn - som behandles af venstrefoldningsfunktionen ( ) foldlfra venstre mod højre, et ord ad gangen ved hjælp af funktionen f, som vedligeholder en arbejdsliste med læste tal og mellemværdier(først [] - en tom liste) og fortolker hvert inputord som et symbol for en aritmetisk funktion eller som et tal, når det evaluerer den endelige værdi af udtrykket ( som vil være den første resterende værdi i arbejdslisten, når inputudtrykkets ordliste er færdig, så den kan hentes derfra ved hjælp af standardfunktionen head).
Her (.)er funktionen kompositionsoperator, (f . g) x = f (g x). For eksempel,
* Main > beregnet "1 2 3 + 4 * - ABS" 19,0Et andet eksempel viser en måde at beregne en uendelig liste af Fibonacci-tal i lineær tid:
fibs = 0 : 1 : zipMed ( + ) fibs ( halefibs ) _Den uendelige liste her er defineret ved hjælp af corecursion- mekanismen - listens efterfølgende værdier er sat baseret på de foregående, med de indledende 0og 1som de to første elementer af listen, og et generatorudtryk zipWith (+) fibs (tail fibs) , der beregner alle elementer startende fra den tredje baseret på de to foregående gennem en standardfunktion, zipWith (+)der parvis summerer elementer af to af sine inputlister.
Denne definition er et eksempel på doven evaluering , som er en væsentlig del af Haskell-sproget. For at forstå, hvordan denne definition fungerer, kan du overveje at beregne de første syv Fibonacci-tal ved hjælp af den:
fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ... + + + + + + halefiber = 1 : 1 : 2 : 3 : 5 : 8 : ... ====== zipMed (+) = 1 : 2 : 3 : 5 : 8 : ... fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ...Det samme kan også skrives ved brug af listespecifikationer ,
fibs = 0 : 1 : [ a + b | ( a , b ) <- zip fibs ( halefibs ) ]eller en udvidelse af Haskell-sproget implementeret i GHC-kompileren ( parallellisteforståelse ) :
fibs = 0 : 1 : [ a + b | a <- fibs | b < - halefiber ]eller med en direkte selvrefererende genererende funktion :
fibs = 0 : 1 : næste fibs hvor næste ( a : t @ ( b : _ )) = ( a + b ) : næste tDisse eksempler viser, hvordan listeudtryk ( listeforståelser ) kan bruges. Implementeringen af at finde alle primtal på den sædvanlige måde ( tjek hvert tal for primegrad ):
-- generel definition (alle naturlige tal > 1, der er primtal) primtal = 2 : [ n | n <- [ 3 .. ], er Prime n ] -- Et tal er primtal, hvis det ikke har nogen (primtal) divisorer isPrime n = foldr ( \ p r -> p * p > n || ( rem n p /= 0 && r )) Sande primtaleller med sigten fra Eratosthenes , i en prototypisk, ineffektiv variant,
primtal = ( korthoved . scanl minus [ 2 .. ] . kort ( \ p -> [ p , p + p .. ]) ) primtaleller effektivt, med strømmene af sammensatte tal, der tidligere var kaskade:
primtal = 2 : _Y (( 3 : ) . minus [ 5 , 7 .. ] . unionAll . map ( \ p -> [ p * p , p * p + 2 * p .. ])) hvor _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 for segment, efter arrays,
import Data.Array import Data.List ( haler , inits ) ps = 2 : [ n | ( r : q : _ , px ) <- ( zip . haler . ( 2 : ) . map ( ^ 2 )) ps ( inits ps ), ( n , True ) <- assocs ( accumArray ( \ _ _ -> False ) Sandt ( r + 1 , q - 1 ) [ ( m , ( ) ) | p < - px , lad s = div ( r + p ) p * p , m < - [ s , s + p .. q - 1 ]] )]ved hjælp af kanoniske funktioner minus, union[27] ):
union ( x : xs ) ( y : ys ) = kasussammenligning x y af 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 ) = kasussammenligning x y af LT -> x : minus xs ( y : ys ) EQ -> minus xs ys GT -> minus ( x : xs ) ) ys minus a b = aEt simpelt eksempel på brug af algebraiske datatyper til at beskrive spillekort. Typeidentifikatorer starter med store bogstaver. Identifikatorer for variabler og funktioner - fra små bogstaver. Nye algebraiske typer er defineret af nøgleordet data. Typesynonymer er defineret af nøgleordet type.
-- Algebraisk type-sum Suit ("opregning"). -- En værdi af kulørtypen kan være en af dem, der er anført til højre -- (eller spar, eller kløver, eller ruder eller hjerter). -- "Suit" fungerer her som en konstruktør af _type_, -- og "Spades", "Clubs" osv. - _data_ konstruktører. data Farbe = Spar | Klubber | Tamburiner | Hjerter -- valgfri automatisk inferens af klasseforekomster -- der giver dig mulighed for at konvertere værdier til strenge (ved hjælp af showfunktionen fra Show) -- og tilbage (ved hjælp af læsefunktionen fra Read), samt sammenligne dem med hinanden -- (ved funktioner af Eq og Ord klasserne). deriving ( Vis , Læs , Eq , Ord ) -- Algebraisk sumtype Værdidata Værdi = Syv | Otte | Ni | Ti | Jack | dame | Konge | Es- afledning ( Vis , Læs , Eq , Ord ) -- Algebraisk type-produktkort ("type-tuple"). -- Værdier af typen Kort er kombinationer af værdier af typerne Value og Suit, -- forenet af datakonstruktøren K. -- Ofte er navnene på datakonstruktøren og typekonstruktøren de samme. datakort = K Værdi Farve deriving ( Vis , Læs , Eq , Ord ) _ -- Et synonym for en liste over værdier af typen Kort. type Hånd = [ Kort ] -- En funktion, der bestemmer, om der er et ægteskab (konge og dronning i samme kulør) i hånden. isMarriage :: Hand -> Bool isMarriage af kortet = - find blot ægteskabet af mindst én kulør ( isMarriageSuits ) [ Spades , Kløver , Ruder , Hjerter ] hvor - tjek om der er både en dame og en konge af den givne kulør m i hånden er MariageSuits m = ( K Dronning m ) ` elem` kort && ( K King m ) ` elem` kort _ _ -- håndeksempler hånd = [ K Kløverdronning , K Seven of Hearts , K Kløverkonge , K Es af Ruder ] hand_without_marriage = [ K Ti af Spades , K King of Spades , K Hjertedronning ] main = tjek håndtjek hånd_uden_ægteskabstjek [] -- tom fordeling hvor tjek kk = putStrLn ( ( vis kk ) ++ " -> " ++ ( vis ( er Margage kk ) ) ) -- Konklusion: -- [Til kløverdronningen, til hjertersyv, til kløverkongen, til ruderes] -> Sandt -- [Til spar ti, til sparkonge, til Hjertedronningen] -> Falsk - [] -> FalskNumerisk integration ved den trapezformede metode:
trapezeIntegrer f a b n = (( sum $ map f [ a + h , a + 2 * h .. b - h ]) + t ) * h hvor t = ( f a + f b ) / 2 h = ( b ) -a ) / n _ main = udskriv $ trapezeIntegrate ( \ x - > x * sin x ) 0 ( 2 * pi ) 100 -- Output: -6,281118086046067Eksemplet nedenfor viser, hvordan man arbejder med Unicode- strenge .
importer Data.Char ( toLower , isAlpha ) palindrom :: [ Char ] -> Bool palindrom s = norm == omvendt norm hvor norm = map to Lower $ filter erAlpha $ s test :: [ Char ] -> IO () test s = putStrLn $ s ++ ": " ++ vis ( palindrom s ) main = test "Og blå i Yenisei" test "En rose faldt på Azors pote" test " Ikke en rose faldt på Azors pote" test "Verden er som Rom" test "Verden er ikke Rom" test "Jeg foretrækker Pi" test "حوت فمه مفتوح" test "Ne mateno, bone tamen" -- Konklusion: -- Og i Yenisei — blå: Sandt -- En rose faldt på Azors pote: Sandt -- Ikke en rose faldt på Azors pote: Falsk -- Verden er som Rom: Sand -- Verden er ikke Rom: Falsk -- Jeg foretrækker Pi: Sandt -- حوت فمه مفتوح: Sandt -- Ne mateno, bone tamen: SandtHaskell er i stigende grad[ float ] brugt i kommercielle miljøer [28] . Dette lettes af traditionen vedtaget i fællesskabet for at frigive biblioteker under liberale licenser (mere end 70 % af frit tilgængelige biblioteker distribueres under betingelserne for BSD, MIT-licenser eller er i det offentlige domæne).
Her er nogle eksempler på kommercielle applikationer skrevet i Haskell: Bluespec SystemVerilog, et indlejret halvlederdesign- og verifikationssprog, er en udvidelse af Haskell-sproget [29] . Cryptol, et kommercielt sprog til udvikling og verifikation af kryptografiske algoritmer, er implementeret i Haskell. Især blev den første formelt verificerede seL4- mikrokerne også skrevet i Haskell.
Haskell bruges aktivt inden for finansiel programmering, risikoanalyse, beslutningsstøttesystemer . Haskell bruges af udviklerne af bylandskabsgeneratoren til spil og simuleringer Gamr7 [30] . Der er eksempler på vellykket anvendelse af sproget til udvikling af private informationssystemer i kommercielle organisationer (herunder dem i SNG-landene) [31] . I den analytiske DBMS SQreamDB er SQL - parsermodulet skrevet i Haskell.
En betydelig del af open source- bibliotekerne og applikationerne skrevet i Haskell er tilgængelige i Hackage-arkivet. Blandt dem er Pandoc universal markup- konverter , den Yi emacs-lignende teksteditor og Leksahs integrerede udviklingsmiljø . Blandt systemudviklingerne er Darcs distribuerede versionskontrolsystem, House -operativsystemet og Xmonad - flisebelagte vinduesmanager .
GHC-kompileren fungerer ofte som en testplads til at teste nye funktionelle programmerings- og optimeringsfunktioner. Samtidig blev sprogkompilatorerne Agda , Curry , Epigram , samt den første kompilator og fortolker af Perl 6 -sproget Pugs (den blev skabt på kun en måned) skrevet i Haskell .
Haskell oversættere | |
---|---|
Tolke |
|
Kompilere |
Programmeringssprog | |
---|---|
|