haskell

Haskell

1. De ontwikkeling van programmeertaal

De bouw van machines om wiskundige berekeningen te maken, startte al vroeg met de Abacus. Het zal echter tot 1936 duren eer dat er een daadwerkelijke bruikbare computer wordt gebouwd. In opdracht 2.1 ga je zelfstandig aan de slag met een overzicht van de geschiedenis van de computer.

Met de komst van het binaire systeem werden ook de programmeertalen geïntroduceerd. De eerste taal die werd ontwikkeld was imperatief. Dat had te maken met de architectuur van de computer. Een imperatieve taal kenmerkt zich doordat alle instructies van boven naar beneden worden gelezen. Hieronder zie je een stukje van de imperatieve programmeertaal C.

c = 1 + 3;
d = c;
c++;
printf(c+d);

Met de komst van het programeren doen tevens twee begrippen hun intrede: geheugen en functies. Functies spelen ook in de wiskunde een centrale rol. Ze leggen een verband tussen de invoer en de uitvoer en kunnen tevens dienen als een black box.

 https://images.computational.nl/galleries/haskell/2016-11-13_11-54-47.png

Omdat computertijd vroeger heel duur was maar tegenwoordig steeds goedkoper en sneller ontwikkeld de programmeertaal zich meer en meer richting menselijke belevingswereld. Haskell is een voorbeeld van een taal wat zich meer richting de menselijke belevingswereld heeft ontwikkelde. We noemen dit een functionele programmeertaal. Desalniettemin zal het in eerste instantie toch vrij abstract overkomen mede omdat het programmeren via de commandprompt gaat.

In onderstaande Prezi presentatie geven we een overzicht van de geschiedenis van de computer. De theoretische basis voor het imperatief programmeren is in de jaren dertig gelegd door wetenschappers zoals Alan Turing en John voin Neumann. De theorie van functies begint al in 1777 bij Leonhard Euler. Hij voerde bijvoorbeeld het gebruik van de Griekse letter π  in als verhouding van de omtrek van de cirkel tot zijn middellijn. Het zou tot 1950 duren voordat iemand op het idee kwam om deze functie-theorie te gebruiken als basis voor het programmeren.

Ga naar de Prezi op prezi.com.

2. Wat is Haskell

De basis van deze cursus is de website http://learnyouahaskell.com/ . We hebben geprobeerd deze cursus zo begrijpelijk mogelijk te maken voor leerlingen uit het voortgezet onderwijs.

Haskell is een functionele programmeertaal. Dat is wat anders dan een imperatieve of procedurele programmeertaal. Een voorbeeld hiervan is als volgt (in de taal C):

a = 1 + 2; //geef variabele a de waarde 1 + 2

c=1; //geef variabele c de waarde 1

b=a; //geef variabele b de waarde van variabele a

c++; //hoog c op met 1

printf(a+b+c); //print de opgetelde waarden van de drie variabelen naar het scherm

Vaak wordt als tegenhanger van imperatief programmeren het object geörienteerd programmeren (ook wel aangeduid als OO-programmeren). Voorbeeldenvan OO-programmeren vind je in de cursus een interactieve applicatie. Een voorbeeld van een bekendere functionele programmeertaal is Javascript.

wiskunde

De taal Haskell zit heel dicht tegen de wiskunde aan. Neem bijvoorbeeld de volgende wiskundige functie:

y = x2 + 3x

Tegenwoordig wordt dit ook opgeschreven als

f(x) = x2 + 3x

We kunnen zeggen de functie f met x als input. De parameter x noemen we dan een argument of een invoer.

In Haskelll wordt deze functie als volgt gemaakt:

f x = x*x + 3*x

Meer parameters kan ook

f(x,y) = x2 + 3y + 2

Haskell:

f x y = x*x + 3*y + 2

We kunnen zelfs de functie f weer in een nieuwe functie opnemen.

 

3. Software installeren

Voor deze cursus gaan we werken met een Haskell compiler. Deze is te downloaden op http://hackage.haskell.org/platform/. Neem de minimale versie en let erop of je een 32-bit of 64-bit computer hebt. Dit is te vinden door in verkenner op Deze pc (afhankelijk van je windows versie)

https://images.computational.nl/galleries/haskell/2016-10-29_11-20-05.png

Hierna kun je een aantal keren op next klikken om de compiler te installeren. Het kan even duren eer het klaar is.

Als het programma is geïnstalleerd open je een terminal window. In de opdrachtprompt kun je de compiler starten door ghci in te typen. Wij zullen vanaf nu met deze prompt werken. Je bent echter vrij om de standaard prompt te gebruiken.

GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
Prelude> :set prompt "ghci> "
ghci>

GHCI staat voor The Glasgow Haskell Compiler. Een compiler is een computerprogramma dat een in een brontaal geschreven programma vertaalt in een equivalent programma van de doeltaal.

4. Je eerste code in Haskell

We zullen nu eerste code uitproberen. Haskell kan functioneren als een rekenmachine. Probeer de volgende berekeningen maar eens uit:

https://images.computational.nl/galleries/haskell/2016-10-30_16-25-08.png

Je kunt ook werken met negatieve getallen. Je zult hierbij echter wel moeten werken met haken want anders krijg je een Precedence parcing error.

https://images.computational.nl/galleries/haskell/2016-10-30_16-34-35.png

Haskell geeft hier heel duidelijk aan wat er aan de hand is:

cannot mix `*' [infixl 7] and prefix `-' [infixl 6] in the same infix expression

 Tussen haken gaat het dus wel goed.

 

5. True en False

Het booleaanse rekenen is allemaal niet zo spannend

https://images.computational.nl/galleries/haskell/2016-10-30_16-45-27.png

6. Functies in Haskell

Zonder dat je het wist heb je al diverse functies uitgevoerd. De + en de * noemen we infix functies. Dit zegt iets over de manier van opschrijven. Normaal gesproken wordt een functie prefix opgeschreven. Voorbeeld f(x , y). We schrijven niet +(3, 4) maar 3 + 4 of 3 * 4. Dat noemen we infix.

Prefixnotatie is omstreeks 1920 uitgevonden door de Poolse logicus Jan Lukasiewicz als notatie voor de propositielogica. Men spreekt daarom ook wel van Poolse notatie.

Een prefix functie in Haskell is de volgende

ghci> max 7 10
10
ghci> min 3 7
3

 In het vorige onderdeel vond je al voorbeelden van infix functies. Een iets gebruikelijkere term voor een infix functie is een operator. Je kunt een prefix functie omzetten naar een infix functie door middel van back quotes. De functie quot geeft van een deling een geheel getal terug.

ghci> quot 23 3
7
ghci> 23 `quot` 3
7

 

7. Een functie zelf maken

Haskell kent een aantal ingebouwde functies zoals :load, :edit of :type. Het is ook mogelijk om zelf functies te maken. Dit gebeurt in een apart bestand. Om dit te maken open je eerst het programma Netbeans. Hierin maak je een zogenaamde empty file.

https://images.computational.nl/galleries/haskell/2016-11-02_19-47-07.png

Geef de file de naam functions.hs.

Tevens kun je met de cmd-prompt (of met verkenner) het beste even ergens een mapje aanmaken. Bij ons staat het mapje op de D: drive en dit is tevens de drive van Google Drive zodat we meteen een backup hebben.

 https://images.computational.nl/galleries/haskell/2016-11-02_20-06-40.png

Het bestand functions.hs slaan we op in deze map.

https://images.computational.nl/galleries/haskell/2016-11-02_20-10-32.png

 In Netbeans maken we de functie DoubleMe. Merk op dat een functie niet wordt afgesloten met een ; of iets dergelijks. Sla de file opnieuw op met Ctrl-s.

https://images.computational.nl/galleries/haskell/2016-11-02_20-28-01.png

eVrvolgens kun  je dit bestand inladen met het commando :load.

 https://images.computational.nl/galleries/haskell/2016-11-02_20-17-42.png

En nu ben je in staat om de functie uit te voeren. De functie vraagt 1 argument.

https://images.computational.nl/galleries/haskell/2016-11-02_20-32-18.png

Een tweede functie

Je kunt ook een tweede functie maken. Breidt je script uit met de volgende functie.

https://images.computational.nl/galleries/haskell/2016-11-04_11-55-55.png

 Als je het script opnieuw inlaadt kun je de functie gebruiken.

https://images.computational.nl/galleries/haskell/2016-11-04_12-00-36.png

 Je kunt functies ook overnieuw gebruiken wat overzichtelijkere code oplevert.

 

Nog een paar dingen over functies.

  • Functies mogen niet met een hoofdletter beginnen.
  • Als het een stukje code is wat iets teruggeeft (retourneert) dan noemen we dat een expressie. De expressie x + x geeft een dubbele x terug.
  • Een functie heeft doorgaans een of meerdere argumenten of parameters. Als een functie geen argumenten heeft dan noemen we dat een definitie. Een voorbeeld van een defintie is myName = "Piet Klaassen"

8. lijsten

In Haskell wordt veel gebruikt gemaakt van lijsten. Een lijst is vergelijkbaar met een array in Java. Het ziet er als volgt uit.

[4,8,15,16,23,42]  

Je kunt zo'n lijst ook een naam geven met het commando let. Dit maakt de code overzichtelijker.

https://images.computational.nl/galleries/haskell/2016-11-06_11-53-13.png

Op lijsten kun je allerlei functies toepassen zoals de som.

https://images.computational.nl/galleries/haskell/2016-11-06_12-31-49.png

Je kunt lijsten ook aaneenschakelen.

https://images.computational.nl/galleries/haskell/2016-11-06_12-39-33.png

Dit noemen we een concatenate

Dit kan niet.

https://images.computational.nl/galleries/haskell/2016-11-06_12-50-58.png

Dit komt omdat een lijst homogeen dient te zijn. Je kunt er óf integers in opslaan óf characters.

9. Een lijst in een lijst

Een lijst in een lijst opslaan kan ook.

https://images.computational.nl/galleries/haskell/2016-11-07_19-39-22.png

Hier kun je wat technieken op loslaten. Stel je hebt een lijst met 4 nummers 5 en je wilt deze toevoegen aan listInList.

Eerst maak je deze lijst aan en daarna probeer je deze toe te voegen met het concanate symbool ++.

https://images.computational.nl/galleries/haskell/2016-11-07_19-44-59.png

Er onstaat dan een non type-variable foutmelding. Met andere woorden: haskell verwacht een argument van hetzelfde type. Dat moet dus ook een lijst in een lijst zijn.

 

10. Functies op een lijst

We kunnen nog wat belangrijke functies toepassen op een lijst.

https://images.computational.nl/galleries/haskell/2016-11-07_20-02-47.png

Tot slot van dit lesonderdeel nog een wat geavanceerdere functie. Stel dat we de volgende code uitvoeren.

 https://images.computational.nl/galleries/haskell/2016-11-10_20-15-04.png

Je ziet dat we ook op deze manier een lijst kunnen samenstellen. Deze manier van definiëren is rechtstreeks gekoppeld aan de wiskunde. Het "|"-teken noemen we the pipe. Na de pipe gebeurd er niets anders dan in de variabele names drie namen stoppen. We kunnen dit echter ook combineren met een concenate teken.

https://images.computational.nl/galleries/haskell/2016-11-10_20-29-36.png

Je ziet dat er nu een combinatie wordt gemaakt tussen de eerste en de tweede lijst. Het resultaat zijn alle combinaties.

De volgende code ligt dan voor de hand.

https://images.computational.nl/galleries/haskell/2016-11-10_20-33-09.png

 

 

11. Tuples

Soms is het nodig om data te groeperen met verschillende soorten type data. Hiervoor kunnen we een tuple nemen:

ghci> ("Jan", True, 2)
("Jan",True,2)

Je ziet dat het mogelijk is om drie verschillende type data bij elkaar te plaatsen. Als we het type opvragen, geeft Haskell de drie verschillende soorten terug:

 :t ("Jan", True, 2)
("Jan", True, 2) :: Num t => ([Char], Bool, t)

We kunnen tuples ook in een lijst bewaren:

ghci> let tuple = ("Jan", True, 2)
ghci> let tuple2 = ("Kees", False, 3)
ghci> let list = [tuple, tuple2]
ghci> list
[("Jan",True,2),("Kees",False,3)]

Als we echter een derde tuple met een andere samenstelling hier aan toe willen voegen geeft Haskell een foutmelding:

ghci> let tuple 3 = ("Marie",False,"drie")
ghci> let list = [tuple, tuple2, tuple3]

<interactive>:14:20: error:
    * Couldn't match expected type `a -> ([Char], Bool, [Char])'
                  with actual type `([Char], Bool, Integer)'
    * In the expression: tuple2
      In the expression: [tuple, tuple2, tuple3]
      In an equation for `list': list = [tuple, tuple2, tuple3]
    * Relevant bindings include
        list :: [a -> ([Char], Bool, [Char])] (bound at <interactive>:14:5)

Een toepassing van een tuple

Stel dat we een driehoek willen vastleggen. Een driehoek heeft drie zijden; a, b en c. Deze zijn van het type Number.

Dit kunnen we als volgt definiëren:

ghci> let triangle = (1,2,3)
ghci> :t triangle
triangle :: (Num t2, Num t1, Num t) => (t, t1, t2)

Het is een driehoek met zijden a=1, b=2, c=3.

Stel nu dat we een alle mogelijke driehoeken met zijden (a,b,c) kleiner of gelijk dan 10 in een definitie vastleggen en daarna tonen.

let triangles = [ (a,b,c) | a <-[1..10], b <-[1..10], c<-[1..10]]
ghci> triangles
[(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,1,5),(1,1,6),(1,1,7),(1,1,8),(1,1,9),(1,1,10),(1,2,1),(1,2,2),(1,2,3),(1,2,4),(1,2,5),(1,2,6),(1,2,7),(1,2,8),(1,2,9),(1,2,10),(1,3,1),(1,3,2),(1,3,3),(1,3,4),(1,3,5),(1,3,6),(1,3,7),(1,3,8),(1,3,9),(1,3,10),(1,4,1),(1,4,2),(1,4,3),(1,4,4),(1,4,5),(1,4,6),(1,4,7),(1,4,8),(1,4,9),(1,4,10),(1,5,1),(1,5,2),(1,5,3),(1,5,4),(1,5,5),(1,5,6),(1,5,7),(1,5,8),(1,5,9),(1,5,10),(1,6,1),(1,6,2),(1,6,3),(1,6,4),(1,6,5),(1,6,6),(1,6,7),(1,6,8),(1,6,9),(1,6,10),(1,7,1),(1,7,2),(1,7,3),(1,7,4),(1,7,5),(1,7,6),(1,7,7),(1,7,8),(1,7,9),(1,7,10),(1,8,1),(1,8,2),(1,8,3),(1,8,4),(1,8,5),(1,8,6),(1,8,7),(1,8,8),(1,8,9),(1,8,10),(1,9,1),(1,9,2),(1,9,3),(1,9,4),(1,9,5),(1,9,6),(1,9,7),(1,9,8),(1,9,9),(1,9,10),(1,10,1),(1,10,2),(1,10,3),(1,10,4),(1,10,5),(1,10,6),(1,10,7),(1,10,8),(1,10,9),(1,10,10),(2,1,1),(2,1,2),(2,1,3),(2,1,4),(2,1,5),(2,1,6),(2,1,7),(2,1,8),(2,1,9),(2,1,10),(2,2,1),(2,2,2),(2,2,3),(2,2,4),(2,2,5),(2,2,6),(2,2,7),(2,2,8),(2,2,9),(2,2,10),(2,3,1),(2,3,2),(2,3,3),(2,3,4),(2,3,5),(2,3,6),(2,3,7),(2,3,8),(2,3,9),(2,3,10),(2,4,1),(2,4,2),(2,4,3),(2,4,4),(2,4,5),(2,4,6),(2,4,7),(2,4,8),(2,4,9),(2,4,10),(2,5,1),(2,5,2),(2,5,3),(2,5,4),(2,5,5),(2,5,6),(2,5,7),(2,5,8),(2,5,9),(2,5,10),(2,6,1),(2,6,2),(2,6,3),(2,6,4),(2,6,5),(2,6,6),(2,6,7),(2,6,8),(2,6,9),(2,6,10),(2,7,1),(2,7,2),(2,7,3),(2,7,4),(2,7,5),(2,7,6),(2,7,7),(2,7,8),(2,7,9),(2,7,10),(2,8,1),(2,8,2),(2,8,3),(2,8,4),(2,8,5),(2,8,6),(2,8,7),(2,8,8),(2,8,9),(2,8,10),(2,9,1),(2,9,2),(2,9,3),(2,9,4),(2,9,5),(2,9,6),(2,9,7),(2,9,8),(2,9,9),(2,9,10),(2,10,1),(2,10,2),(2,10,3),(2,10,4),(2,10,5),(2,10,6),(2,10,7),(2,10,8),(2,10,9),(2,10,10),(3,1,1),(3,1,2),(3,1,3),(3,1,4),(3,1,5),(3,1,6),(3,1,7),(3,1,8),(3,1,9),(3,1,10),(3,2,1),(3,2,2),(3,2,3),(3,2,4),(3,2,5),(3,2,6),(3,2,7),(3,2,8),(3,2,9),(3,2,10),(3,3,1),(3,3,2),(3,3,3),(3,3,4),(3,3,5),(3,3,6),(3,3,7),(3,3,8),(3,3,9),(3,3,10),(3,4,1),(3,4,2),(3,4,3),(3,4,4),(3,4,5),(3,4,6),(3,4,7),(3,4,8),(3,4,9),(3,4,10),(3,5,1),(3,5,2),(3,5,3),(3,5,4),(3,5,5),(3,5,6),(3,5,7),(3,5,8),(3,5,9),(3,5,10),(3,6,1),(3,6,2),(3,6,3),(3,6,4),(3,6,5),(3,6,6),(3,6,7),(3,6,8),(3,6,9),(3,6,10),(3,7,1),(3,7,2),(3,7,3),(3,7,4),(3,7,5),(3,7,6),(3,7,7),(3,7,8),(3,7,9),(3,7,10),(3,8,1),(3,8,2),(3,8,3),(3,8,4),(3,8,5),(3,8,6),(3,8,7),(3,8,8),(3,8,9),(3,8,10),(3,9,1),(3,9,2),(3,9,3),(3,9,4),(3,9,5),(3,9,6),(3,9,7),(3,9,8),(3,9,9),(3,9,10),(3,10,1),(3,10,2),(3,10,3),(3,10,4),(3,10,5),(3,10,6),(3,10,7),(3,10,8),(3,10,9),(3,10,10),(4,1,1),(4,1,2),(4,1,3),(4,1,4),(4,1,5),(4,1,6),(4,1,7),(4,1,8),(4,1,9),(4,1,10),(4,2,1),(4,2,2),(4,2,3),(4,2,4),(4,2,5),(4,2,6),(4,2,7),(4,2,8),(4,2,9),(4,2,10),(4,3,1),(4,3,2),(4,3,3),(4,3,4),(4,3,5),(4,3,6),(4,3,7),(4,3,8),(4,3,9),(4,3,10),(4,4,1),(4,4,2),(4,4,3),(4,4,4),(4,4,5),(4,4,6),(4,4,7),(4,4,8),(4,4,9),(4,4,10),(4,5,1),(4,5,2),(4,5,3),(4,5,4),(4,5,5),(4,5,6),(4,5,7),(4,5,8),(4,5,9),(4,5,10),(4,6,1),(4,6,2),(4,6,3),(4,6,4),(4,6,5),(4,6,6),(4,6,7),(4,6,8),(4,6,9),(4,6,10),(4,7,1),(4,7,2),(4,7,3),(4,7,4),(4,7,5),(4,7,6),(4,7,7),(4,7,8),(4,7,9),(4,7,10),(4,8,1),(4,8,2),(4,8,3),(4,8,4),(4,8,5),(4,8,6),(4,8,7),(4,8,8),(4,8,9),(4,8,10),(4,9,1),(4,9,2),(4,9,3),(4,9,4),(4,9,5),(4,9,6),(4,9,7),(4,9,8),(4,9,9),(4,9,10),(4,10,1),(4,10,2),(4,10,3),(4,10,4),(4,10,5),(4,10,6),(4,10,7),(4,10,8),(4,10,9),(4,10,10),(5,1,1),(5,1,2),(5,1,3),(5,1,4),(5,1,5),(5,1,6),(5,1,7),(5,1,8),(5,1,9),(5,1,10),(5,2,1),(5,2,2),(5,2,3),(5,2,4),(5,2,5),(5,2,6),(5,2,7),(5,2,8),(5,2,9),(5,2,10),(5,3,1),(5,3,2),(5,3,3),(5,3,4),(5,3,5),(5,3,6),(5,3,7),(5,3,8),(5,3,9),(5,3,10),(5,4,1),(5,4,2),(5,4,3),(5,4,4),(5,4,5),(5,4,6),(5,4,7),(5,4,8),(5,4,9),(5,4,10),(5,5,1),(5,5,2),(5,5,3),(5,5,4),(5,5,5),(5,5,6),(5,5,7),(5,5,8),(5,5,9),(5,5,10),(5,6,1),(5,6,2),(5,6,3),(5,6,4),(5,6,5),(5,6,6),(5,6,7),(5,6,8),(5,6,9),(5,6,10),(5,7,1),(5,7,2),(5,7,3),(5,7,4),(5,7,5),(5,7,6),(5,7,7),(5,7,8),(5,7,9),(5,7,10),(5,8,1),(5,8,2),(5,8,3),(5,8,4),(5,8,5),(5,8,6),(5,8,7),(5,8,8),(5,8,9),(5,8,10),(5,9,1),(5,9,2),(5,9,3),(5,9,4),(5,9,5),(5,9,6),(5,9,7),(5,9,8),(5,9,9),(5,9,10),(5,10,1),(5,10,2),(5,10,3),(5,10,4),(5,10,5),(5,10,6),(5,10,7),(5,10,8),(5,10,9),(5,10,10),(6,1,1),(6,1,2),(6,1,3),(6,1,4),(6,1,5),(6,1,6),(6,1,7),(6,1,8),(6,1,9),(6,1,10),(6,2,1),(6,2,2),(6,2,3),(6,2,4),(6,2,5),(6,2,6),(6,2,7),(6,2,8),(6,2,9),(6,2,10),(6,3,1),(6,3,2),(6,3,3),(6,3,4),(6,3,5),(6,3,6),(6,3,7),(6,3,8),(6,3,9),(6,3,10),(6,4,1),(6,4,2),(6,4,3),(6,4,4),(6,4,5),(6,4,6),(6,4,7),(6,4,8),(6,4,9),(6,4,10),(6,5,1),(6,5,2),(6,5,3),(6,5,4),(6,5,5),(6,5,6),(6,5,7),(6,5,8),(6,5,9),(6,5,10),(6,6,1),(6,6,2),(6,6,3),(6,6,4),(6,6,5),(6,6,6),(6,6,7),(6,6,8),(6,6,9),(6,6,10),(6,7,1),(6,7,2),(6,7,3),(6,7,4),(6,7,5),(6,7,6),(6,7,7),(6,7,8),(6,7,9),(6,7,10),(6,8,1),(6,8,2),(6,8,3),(6,8,4),(6,8,5),(6,8,6),(6,8,7),(6,8,8),(6,8,9),(6,8,10),(6,9,1),(6,9,2),(6,9,3),(6,9,4),(6,9,5),(6,9,6),(6,9,7),(6,9,8),(6,9,9),(6,9,10),(6,10,1),(6,10,2),(6,10,3),(6,10,4),(6,10,5),(6,10,6),(6,10,7),(6,10,8),(6,10,9),(6,10,10),(7,1,1),(7,1,2),(7,1,3),(7,1,4),(7,1,5),(7,1,6),(7,1,7),(7,1,8),(7,1,9),(7,1,10),(7,2,1),(7,2,2),(7,2,3),(7,2,4),(7,2,5),(7,2,6),(7,2,7),(7,2,8),(7,2,9),(7,2,10),(7,3,1),(7,3,2),(7,3,3),(7,3,4),(7,3,5),(7,3,6),(7,3,7),(7,3,8),(7,3,9),(7,3,10),(7,4,1),(7,4,2),(7,4,3),(7,4,4),(7,4,5),(7,4,6),(7,4,7),(7,4,8),(7,4,9),(7,4,10),(7,5,1),(7,5,2),(7,5,3),(7,5,4),(7,5,5),(7,5,6),(7,5,7),(7,5,8),(7,5,9),(7,5,10),(7,6,1),(7,6,2),(7,6,3),(7,6,4),(7,6,5),(7,6,6),(7,6,7),(7,6,8),(7,6,9),(7,6,10),(7,7,1),(7,7,2),(7,7,3),(7,7,4),(7,7,5),(7,7,6),(7,7,7),(7,7,8),(7,7,9),(7,7,10),(7,8,1),(7,8,2),(7,8,3),(7,8,4),(7,8,5),(7,8,6),(7,8,7),(7,8,8),(7,8,9),(7,8,10),(7,9,1),(7,9,2),(7,9,3),(7,9,4),(7,9,5),(7,9,6),(7,9,7),(7,9,8),(7,9,9),(7,9,10),(7,10,1),(7,10,2),(7,10,3),(7,10,4),(7,10,5),(7,10,6),(7,10,7),(7,10,8),(7,10,9),(7,10,10),(8,1,1),(8,1,2),(8,1,3),(8,1,4),(8,1,5),(8,1,6),(8,1,7),(8,1,8),(8,1,9),(8,1,10),(8,2,1),(8,2,2),(8,2,3),(8,2,4),(8,2,5),(8,2,6),(8,2,7),(8,2,8),(8,2,9),(8,2,10),(8,3,1),(8,3,2),(8,3,3),(8,3,4),(8,3,5),(8,3,6),(8,3,7),(8,3,8),(8,3,9),(8,3,10),(8,4,1),(8,4,2),(8,4,3),(8,4,4),(8,4,5),(8,4,6),(8,4,7),(8,4,8),(8,4,9),(8,4,10),(8,5,1),(8,5,2),(8,5,3),(8,5,4),(8,5,5),(8,5,6),(8,5,7),(8,5,8),(8,5,9),(8,5,10),(8,6,1),(8,6,2),(8,6,3),(8,6,4),(8,6,5),(8,6,6),(8,6,7),(8,6,8),(8,6,9),(8,6,10),(8,7,1),(8,7,2),(8,7,3),(8,7,4),(8,7,5),(8,7,6),(8,7,7),(8,7,8),(8,7,9),(8,7,10),(8,8,1),(8,8,2),(8,8,3),(8,8,4),(8,8,5),(8,8,6),(8,8,7),(8,8,8),(8,8,9),(8,8,10),(8,9,1),(8,9,2),(8,9,3),(8,9,4),(8,9,5),(8,9,6),(8,9,7),(8,9,8),(8,9,9),(8,9,10),(8,10,1),(8,10,2),(8,10,3),(8,10,4),(8,10,5),(8,10,6),(8,10,7),(8,10,8),(8,10,9),(8,10,10),(9,1,1),(9,1,2),(9,1,3),(9,1,4),(9,1,5),(9,1,6),(9,1,7),(9,1,8),(9,1,9),(9,1,10),(9,2,1),(9,2,2),(9,2,3),(9,2,4),(9,2,5),(9,2,6),(9,2,7),(9,2,8),(9,2,9),(9,2,10),(9,3,1),(9,3,2),(9,3,3),(9,3,4),(9,3,5),(9,3,6),(9,3,7),(9,3,8),(9,3,9),(9,3,10),(9,4,1),(9,4,2),(9,4,3),(9,4,4),(9,4,5),(9,4,6),(9,4,7),(9,4,8),(9,4,9),(9,4,10),(9,5,1),(9,5,2),(9,5,3),(9,5,4),(9,5,5),(9,5,6),(9,5,7),(9,5,8),(9,5,9),(9,5,10),(9,6,1),(9,6,2),(9,6,3),(9,6,4),(9,6,5),(9,6,6),(9,6,7),(9,6,8),(9,6,9),(9,6,10),(9,7,1),(9,7,2),(9,7,3),(9,7,4),(9,7,5),(9,7,6),(9,7,7),(9,7,8),(9,7,9),(9,7,10),(9,8,1),(9,8,2),(9,8,3),(9,8,4),(9,8,5),(9,8,6),(9,8,7),(9,8,8),(9,8,9),(9,8,10),(9,9,1),(9,9,2),(9,9,3),(9,9,4),(9,9,5),(9,9,6),(9,9,7),(9,9,8),(9,9,9),(9,9,10),(9,10,1),(9,10,2),(9,10,3),(9,10,4),(9,10,5),(9,10,6),(9,10,7),(9,10,8),(9,10,9),(9,10,10),(10,1,1),(10,1,2),(10,1,3),(10,1,4),(10,1,5),(10,1,6),(10,1,7),(10,1,8),(10,1,9),(10,1,10),(10,2,1),(10,2,2),(10,2,3),(10,2,4),(10,2,5),(10,2,6),(10,2,7),(10,2,8),(10,2,9),(10,2,10),(10,3,1),(10,3,2),(10,3,3),(10,3,4),(10,3,5),(10,3,6),(10,3,7),(10,3,8),(10,3,9),(10,3,10),(10,4,1),(10,4,2),(10,4,3),(10,4,4),(10,4,5),(10,4,6),(10,4,7),(10,4,8),(10,4,9),(10,4,10),(10,5,1),(10,5,2),(10,5,3),(10,5,4),(10,5,5),(10,5,6),(10,5,7),(10,5,8),(10,5,9),(10,5,10),(10,6,1),(10,6,2),(10,6,3),(10,6,4),(10,6,5),(10,6,6),(10,6,7),(10,6,8),(10,6,9),(10,6,10),(10,7,1),(10,7,2),(10,7,3),(10,7,4),(10,7,5),(10,7,6),(10,7,7),(10,7,8),(10,7,9),(10,7,10),(10,8,1),(10,8,2),(10,8,3),(10,8,4),(10,8,5),(10,8,6),(10,8,7),(10,8,8),(10,8,9),(10,8,10),(10,9,1),(10,9,2),(10,9,3),(10,9,4),(10,9,5),(10,9,6),(10,9,7),(10,9,8),(10,9,9),(10,9,10),(10,10,1),(10,10,2),(10,10,3),(10,10,4),(10,10,5),(10,10,6),(10,10,7),(10,10,8),(10,10,9),(10,10,10)]

 We krijgen dan een lange lijst van tuples van alle mogelijke combinaties.

We gaan dit nu beperken naar een lijst van rechthoekige driehoeken met behulp van de stelling van Pythagoras.

https://images.computational.nl/galleries/haskell/2016-11-11_09-58-51.png

ghci> let triangles = [ (a,b,c) | a <-[1..10], b <-[1..10], c<-[1..10], a^2 + b^2 == c^2]
ghci> triangles
[(3,4,5),(4,3,5),(6,8,10),(8,6,10)]

Je ziet dat we na de komma een voorwaarde hebben gesteld met behulp van de stelling van Pythagoras. We kunnen nu dus vrij snel alle mogelijke rechthoeken tonen met zijde kleiner of gelijk aan 10.

Anders dan in een lijst is het in een tuple toegestaan om meerdere typen data te combinareren zoals bijvoorbeeld (1, "a"). Een tuple met 2 elementen noemen we een 2-tuple. Tuples met 3 elementen heten een 3-tuple etc.