Haskell (programmeringssprog)
Haskell er navnet på et rent funktionsprogrammeringssprog med en ikke-striks ("doven") semantik og stærke, statiske typer. Det er opkaldt efter logikeren Haskell Curry.
Historie
[redigér | rediger kildetekst]Efter Research Software Ltd. i 1985 udviklede programmeringssproget Miranda steg interessen for dovent evaluerede programmeringssprog. Til konferencen Functional Programming Languages and Computer Architecture (FPCA) i 1987 i Portland, Oregon blev man enige om behovet for en komité til at varetage en åben standard for sådanne sprog. Komitéens formål skulle derfor være at sætte de eksisterende sprog sammen til ét sprog, hvis formål skulle være grundlaget for ny forskning i funktionsprogrammeringssprog.
Komitéens arbejde resulterede i 1990 i Haskell 1.0-standarden som senere blev opdateret med 1.1, 1.2, 1.3 og 1.4. I slutningen af 1997 blev Haskell 98-standarden udgivet med formålet at angive en stabil, minimal og portabel version af sproget, samt et standardbibliotek til undervisningsbrug og videre udvidelse. Komitéen gav eksplicit udtryk for at skabelsen af nye udvidelser var velønskede.
I februar 1999 blev Haskell 98-standarden udgivet under navnet The Haskell 98 Report. I januar 2003 udkom en revideret udgave under navnet Haskell 98 Language and Libraries: The Revised Report. Sproget er i stadig udvikling og den mest populære compiler til sproget, Glasgow Haskell Compiler (GHC), er udgangspunktet for de fleste udvidelser såsom generaliserede, algebraiske datatyper og typefamilier.
Tidligt i 2006 påbegyndtes endnu en revision af standarden for sproget under navnet Haskell Prime med henblik på at udgive årlige revisioner. Den første årlige revision under dette initiativ var Haskell 2010 som blev annonceret i november 2009 og udgivet i juli 2010.
Egenskaber
[redigér | rediger kildetekst]Haskell understøtter doven evaluering, mønstergenkendelse, list comprehension, typeklasser, typepolymorfi og typeinferens. Det er et rent funktionsprogrammeringssprog, hvilket betyder at funktioner generelt ikke har bivirkninger, og at de derfor modellerer sig tæt op af den matematiske definition for funktioner. En bivirkning skal forstås som en del af et programs resultat, som ikke alene fremgår af returværdien for en funktion (for eksempel I/O).
Haskell har et stærkt, statisk typesystem baseret på Hindley-Milner-typeinferens. Haskells primære innovation i denne retning er tilføjelsen af typeklasser, som oprindeligt var tiltænkt som en måde at tilføje overloading, men som sidenhen har fundet mange flere anvendelser.
Sproget har en åben standard og adskillige implementeringer eksisterer af denne.
Der eksisterer desuden et aktivt miljø omkring sproget og mere end 3600 tredjeparts-open source-moduler findes i Hackage-pakkedepotet.
Eksempler
[redigér | rediger kildetekst]Hello World
[redigér | rediger kildetekst]Følgende er Hello World-programmet skrevet i Haskell. Det er værd at bemærke at alle linjer foruden den sidste kan udelades, men i større programmer har en strukturerende betydning:
module Main where
main :: IO ()
main = putStrLn "Hello, World!"
Fakultetsfunktionen
[redigér | rediger kildetekst]Følgende er fakultetsfunktionen skrevet på forskellige måder:
-- Typeannotering (valgfri):
factorial :: Integer -> Integer
-- Ved brug af rekursion og mønstergenkendelse
factorial 0 = 1
factorial n = n * factorial (n - 1)
-- Ved brug af rekursion uden mønsterkendelse
factorial n = if n > 0 then n * factorial (n-1) else 1
-- Ved at bruge en liste og en biblioteksfunktion
factorial n = product [1..n]
-- Ved at bruge en liste og foldning (funktionsprogrammeringsbegreb)
factorial n = foldl1 (*) [1..n]
-- Ved at bruge punktfri stil hvor argumentet til funktionen gøres implicit
factorial = foldr (*) 1 . enumFromTo 1
Fibonacci-tal
[redigér | rediger kildetekst]Følgende er effektive implementeringer af Fibonacci-tallene som uendelige lister:
-- Typeannotering (valgfri):
fib :: Int -> Integer
-- Med selv-refererende data
fib n = fibs !! n
where fibs = 0 : scanl (+) 1 fibs
-- 0,1,1,2,3,5,...
-- Samme som ovenstående, uden brug af scanl-biblioteksfunktionen
fib n = fibs !! n
where fibs = 0 : 1 : next fibs
next (a : t@(b:_)) = (a+b) : next t
-- Lignende fremgangsmåde som anvender zipWith-biblioteksfunktionen
fib n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
-- Ved at definere en generator-funktion
fib n = fibs (0,1) !! n
where fibs (a,b) = a : fibs (b,a+b)
Typen "Int" hentyder til heltal med en størrelse begrænset af maskinens registre (brugt som et indeks ind i lister ved hjælp af !!-operatoren), mens "Integer" kan bruges for at opnå heltalsværdier af vilkårlig størrelse. For eksempel kan ovenstående kode anvendes til hurtigt at beregne det 10.000. Fibonacci-tal som et 2090-cifret tal