Haskell

**Haskell** er et standardisert, rent funksjonelt programmeringsspråk navngitt etter matematikeren Haskell Curry. Haskell har såkalt sterk typesetting og lat evaluering, og finnes i flere implementasjoner, der GHC kanskje er den mest kjente.

Som i andre funksjonelle språk er programmer skrevet i Haskell først og fremst konstruert ut ifra funksjonskall. Alle variabler er lokale, og kan ikke endres underveis; fremfor iterasjon brukes oftest rekursjon. Språket er dypt forankret i Currys forskning og har en mer matematisk tilnærming til programmering enn imperative språk.

Siden Haskell er et rent funksjonelt programmeringsspråk, kan ikke funksjoner ha bivirkninger. Med andre ord kan ikke funksjoner endre verdier tilgjengelig andre steder i koden – de kan kun sette sine egne lokale verdier samt returnere disse, men ved bruk av konseptet monader kan man kontrollert etterligne denne oppførselen der det trengs.

## Historie

Haskell ble skapt som et standardisert språk etter stor etterspørsel etter et rent funksjonelt språk som kunne samle de mange mindre funksjonelle språkene som alle delte flere likhetstrekk i syntaks og funksjonalitet. Det var spesielt funksjonalitet som lat evaluering som bidro til ønsket om et standardisert språk.

Under konferansen *Functional Programming Languages and Computer Architecture* i Portland, Oregon i september 1987 ble en komité satt opp for å utvikle spesifikasjonene til språket. Første møte ble holdt i juli året etter. Språket ble kalt Haskell, etter matematikeren Haskell Curry, kjent for sitt arbeid innen kombinatorisk logikk. I forkant av navngivningen av programmeringsspråket forhørte Paul Hudak og David Wise seg med enken til Haskell, Virginia, om hennes tillatelse om å bruke ektemannens navn. På et senere tidspunkt besøkte enken et foredrag som Hudak holdt om Haskell og sa «Du vet, Haskell likte egentlig aldri navnet sitt.»

Den første utgaven av Haskell, kalt *Haskell 1.0* ble utgitt i 1990, fulgt av versjonene 1.1 (1991), 1.2 (1992), 1.3 (1996) og 1.4 (1997). Av disse ble flest endringer gjennomført i versjon 1.3, der blant annet *do*-kommandoen, *IO-monaden* og *typeklasser* ble innført.

### Idéen bak Haskell

Før det fantes noen spesifikasjon eller implementasjon av Haskell ble det utviklet en liste over mål som programmeringsspråket skulle oppfylle.

# Det måtte være passelig for læring, forskning og applikasjoner – inkludert store, komplekse systemer
# Det skulle være beskrevet fullstendig i form av formell syntaks og semantikk.
# Det skulle være fritt tilgjengelig. Enhver skulle kunne implementere språket, og distribuere det som de ønsker.
# Det skulle være mulig å bruke det som grunnlag for fremtidig forskning innenfor programmeringsspråk.
# Det skulle være basert på idéer som var attraktive for folk flest og samlet konsensus.
# Det skulle redusere unødvendig ulikheter i funksjonelle programmeringsspråk

### Haskell 98
På slutten av 1997 begynte arbeidet med å forme en ny utgave av Haskell. Ved utgivelsen av spesifikasjonene til Haskell 98 siktet komitéen seg inn på å spesifisere en stabil, minimal og høyst portabel versjon av språket. Spesifikasjonen inkluderte et standardbibliotek for læring, og la en basis for videre utvidelser av språket. Dette har blant annet blitt utnyttet av kompilatoren og hovedimplementasjonen av Haskell, Glasgow Haskell Compiler (GHC), i videre utvikling av språket. Dette var den siste endringen gjennomført av den opprinnelige komiteen.

Haskell 98 ble utgitt i 1999 under navnet *The Haskell 98 Report*. I 2003 kom en revidert utgave kalt *Haskell 98 Language and Libraries: The Revised Report*. Språket fortsatte å utvikles og utvides, med GHC i spissen.

#### Haskell 2010
I 2006 ble arbeidet med å en ny oppdatering av språket begynt, kalt *Haskell Prime*. Denne prosessen skulle være kontinuerlig, og målet var å oppdatere Haskell-spesifikasjonen med en revidert utgave hvert år. Den første utgaven som faller under Haskell Prime er Haskell 2010, som ble annonsert i november 2009 og publisert i juli 2010 av Simon Marlow. Under annonseringen av Haskell 2010 ble det også presisert at formasjonen av komitéen for den neste utgaven, Haskell 2011, er underveis.

Blant de store forandringene siden Haskell 98 gir 2010-utgaven et grensesnitt mot andre språk, også kalt *foreign function interface* (FFI). Haskell 2010 tillater også kildekoden å spesifisere enkelte krav for kompilering, som krav til utvidelser og versjon av Haskell. Navnene på utvidelsene som ble introdusert med Haskell 2010 er DoAndIfThenElse, HierarchicalModules, EmptyDataDeclarations, FixityResolution, ForeignFunctionInterface, LineCommentSyntax, PatternGuards, RelaxedDependencyAnalysis, LanguagePragma, NoNPlusKPatterns.

## Kode og syntaks
### Eksempler – grunnleggende syntaks
Hello World kan i Haskell skrives 

```haskell
main :: IO ()
main = putStrLn "Hello, World!"
```

eller bare (siden Haskell bruker implisitt typededuksjon, dvs. selv evaluerer typer for argumenter og resultater)

```haskell
main = putStrLn "Hello, World!"
```

I det siste eksempelet er *deklarasjonen* til funksjonen tatt bort.

Funksjoner i Haskell kan bli definert først med navn og type separert med to kolon (*::*). Typedeklareringen viser hvilke typer argumenter en funksjon kan få passert, den siste typedeklareringen gjelder det som returneres av funksjonen; siste vil alltid være med.

En funksjon som legger sammen to tall se slik ut:

```haskell
add :: Integer -> Integer -> Integer
add x y =  x + y
```


En funksjon kan aldri endre tilstander andre steder i koden (ingen bivirkninger), og må alltid returnere noe. Dette er ulikt mange imperative språk, der man kan kalle en funksjon for å gjøre endringer i parametrene gitt til funksjonen (f.eks. ved sortering av en array).

### Mønstertrefning
En funksjon må ha minst én definisjon, dvs. man må angi hvilke operasjoner som skal gjøres ved kall på denne funksjonen. Det er mulig – og vanlig – å angi flere definisjoner dersom argumentene til en funksjon kan være av flere typer; dette er vanlig blant annet for å angi ulike tilfeller for rekursive kall. Denne funksjonaliteten kalles *mønstertreffning*: Funksjonen analyserer innkommende argumenter mot et mønster som er spesifisert i funksjonsdeklareringen.

En funksjon for å regne ut fakultet for et tall (produktet av alle tall fra 1 til *n*, der *n* er større eller lik enn 0 – 0! er definert til å være 1) kan se slik ut:

```haskell
fakultet :: Integer -> Integer
fakultet 0 = 1
fakultet n | n > 0 = n * fakultet (n-1)
```

Her ser man at funksjonen først sjekker om *0* blir passert til funksjonen, viser det seg å være sant returnerer den *1*, hvis ikke fortsetter den videre til den treffer et mønster som passer.

Et annet enkelt eksempel på mønstertreffing vil være følgende funksjon, der resultatet på funksjonen blir annerledes ut ifra hvilken bokstav funksjonen får passert.


```haskell
bokstavNavn :: Char -> String  
bokstavNavn 'a' = "Andreas"  
bokstavNavn 'b' = "Bodil"  
bokstavNavn 'c' = "Cato"
```


Et litt mer avansert eksempel på mønstertreffing vil være 3 funksjoner som hver tar et generiske sett med 3 objekter. taNummerEn treffer første objektet i settet og binder den til variabelen *x*, for så å returnere denne. taNummerTo treffer andre objektet og binder den til *y*, taNummerTre treffer siste og tredje objektet og binder det til *z* og i likhet med første funksjon returnerer alle det objektet de treffer.


```haskell
taNummerEn :: (a, b, c) -> a  
taNummerEn (x, _, _) = x
```


```haskell
taNummerTo :: (a, b, c) -> b  
taNummerTo (_, y, _) = y
```


```haskell
taNummerTre :: (a, b, c) -> c  
taNummerTre (_, _, z) = z
```


## Implementasjoner
En del av tanken bak Haskell at det skulle være en fri og åpen spesifikasjon med flere implementasjoner. GHC er den mest brukte kompilatoren for Haskell, og har også flere egne utvidelser til Haskell. én av disse er et grensesnitt til Microsoft Windows. GHC kompilerer Haskell kode ned til det aktuelle operativsystemet sin egen kode, som gjør at det ikke trenger å kjøres via en virtuell maskin.

Andre implementasjoner er:

* Gofer, en dialekt utviklet til akademisk bruk. Hadde en tilleggsfunksjon kalt «konstruktklasser» utviklet av Mark Jones.
* HBC, en eldre implementasjon som ikke lenger blir vedlikeholdt. Kompilerer også til operativsystemers egen kode.
* Helium, en nyere og lettere versjon av Haskell som skal gjøre læring av språket enklere. På grunn av at det mangler støtte for typeklasser vil mange Haskell-applikasjoner ikke kunne kompileres med denne kompilatoren.
* Utrecht Haskell Compiler (UHC) er en Haskell-implementasjon fra Universitetet i Utrecht. Støtter nesten alle Haskell 98-funksjonene i tillegg til en del eksperimentelle utvidelser. Språket er hovedsakelig brukt til akademisk forskning innenfor genererte typesystemer og språkutvidelser.
* Hugs, Haskell User's Gofer System, er en lett og portabel Haskell-kompilator som kompilerer til bytekode. Hugs gir kjapp kompilering av applikasjoner og er relativt kjapp under kjøring. 
* Jhc er en Haskell-kompilator skrevet av John Meacham. Kompilatoren setter fokus på hastighet og effektivitet av genererte programmet, samt utforskning av nye programendringer. LHC er en nylig fork av Jhc.
* nhc98 er en annen bytekode-kompilator. Nhc98 er kompatibelt med Haskell 98-spesifikasjonen og fokuserer veldig på å minimisere minnebruk. Dette gjør at Nhc98 er spesielt god på eldre og litt tregere maskiner.
* Yhc, York Haskell Compiler var en fork av nhc98. Målet var å være enklere, mer portabel og effektiv. Yhc integrerte støtte for Hat, en Haskell tracer. Til forandring fra de andre inkluderte også Yhc en JavaScript-motor som lot brukeren kjøre Haskell-applikasjoner i en nettleser.

## Utviklingsmiljø
Det finnes svært få dedikerte utviklingsmiljø til Haskell så flere foretrekker å bruke mer generiske tekstredigeringsprogrammer som Emacs, TextMate, Subtext og vi. Disse programmene har som regel støtte for Haskell-syntakse og fremhever denne med farger og andre effekter.

Den største applikasjonen som tilbyr et integrerte utviklingsmiljø til Haskell er Leksah (Haskel baklengs). Leksah er skrevet i Haskell og er gitt ut under GPL. Med Leksah har utviklere muligheten til å formulere kode i et eget grafisk, integrert miljø med autofullføring av syntakse, import av biblioteker og integrasjon mot cabal; pakkesystemet til Haskell. Et annet verktøy skrevet i Haskell er Yi. Dette verktøyet minner svært om Vim og har mulighet til å integreres mot både Vim, Emacs og andre.

Man finner også tilleggsfunksjoner til andre etablerte integrerte utviklingsmiljø, som for eksempel Eclipse

## Referanser


## Eksterne lenker
* 
*  Glasgow Haskell Compiler, en Haskell implementasjon 
*  Learn You a Haskell for Great Good! (En populær læreressurs)