TIES542 kevät 2009 Tyyppiteorian alkeet

Samankaltaiset tiedostot
Staattinen tyyppijärjestelmä

TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia

Geneeriset tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

TIES542 kevät 2009 Rekursiiviset tyypit

Haskell ohjelmointikielen tyyppijärjestelmä

Ydin-Haskell Tiivismoniste

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Yksinkertaiset tyypit

Ehto- ja toistolauseet

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 16. toukokuuta 2011

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 26. kesäkuuta 2013

Alityypitys. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Java-kielen perusteet

Rekursiiviset tyypit

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

TIEA255 Tietotekniikan teemaseminaari ohjelmointikielet ja kehitysalustat. Antti-Juhani Kaijanaho. 16. helmikuuta 2011

Tietotyypit ja operaattorit

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

TIES542 kevät 2009 Denotaatio

14.1 Rekursio tyypitetyssä lambda-kielessä

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Attribuuttikieliopit

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Demo 7 ( ) Antti-Juhani Kaijanaho. 9. joulukuuta 2005

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne.

Oliot ja tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

formalismeja TIEA241 Automaatit ja kieliopit, syksy 2015 Antti-Juhani Kaijanaho 15. joulukuuta 2015 TIETOTEKNIIKAN LAITOS

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

lausekkeiden tapauksessa. Jotkin ohjelmointikielet on määritelty sellaisiksi,

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

Harjoitustyö: virtuaalikone

Palautetta viime luennosta

Java-kielen perusteita

1.3Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ITKP102 Ohjelmointi 1 (6 op)

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

JavaScript alkeet Esimerkkikoodeja moniste 2 ( Metropolia)

sama tyyppi (joka vastaa kaikkien mahdollisten arvojen summa-aluetta). Esimerkiksi

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 30. marraskuuta 2015

Java-kielen perusteet

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Uusi näkökulma. TIEA341 Funktio ohjelmointi 1 Syksy 2005

13. Loogiset operaatiot 13.1

Muuttujien roolit Kiintoarvo cin >> r;

Ohjelmoinnin peruskurssien laaja oppimäärä

5.5 Jäsenninkombinaattoreista

Osoitin ja viittaus C++:ssa

Luku 15. Parametripolymorfismi Kumitus

AS C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

11/20: Konepelti auki

Taas laskin. TIES341 Funktio ohjelmointi 2 Kevät 2006

Kontekstittomien kielten jäsentäminen Täydentäviä muistiinpanoja TIEA241 Automaatit ja kieliopit, syksy 2016

TIEA341 Funktio-ohjelmointi 1, kevät 2008

16. Ohjelmoinnin tekniikkaa 16.1

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 16. helmikuuta 2012

Laajennetaan vielä Ydin-Haskellia ymmärtämään vakiomäärittelyt. Määrittely on muotoa

PERL. TIE Principles of Programming Languages. Ryhmä 4: Joonas Lång & Jasmin Laitamäki

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

Ohjelmoinnin perusteet Y Python

16. Ohjelmoinnin tekniikkaa 16.1

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

2.4 Normaalimuoto, pohja ja laskentajärjestys 2.4. NORMAALIMUOTO, POHJA JA LASKENTAJÄRJESTYS 13

Ohjelmoinnin peruskurssien laaja oppimäärä

811120P Diskreetit rakenteet

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

System.out.printf("%d / %d = %.2f%n", ekaluku, tokaluku, osamaara);

Esimerkki 1: Kahviautomaatti.

1.3 Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 12. kesäkuuta 2013

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIES542 kevät 2009 Oliokielten erityispiirteitä

Sisällys. 17. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. for-lause lyhemmin

Tieto ja sen osoite (3) Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI) Osoitinmuuttujat. Tieto ja sen osoite (5)

Ruby. Tampere University of Technology Department of Pervasive Computing TIE Principles of Programming Languages

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

Tietueet. Tietueiden määrittely

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Sisällys. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Sisällys. 16. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. Aritmetiikkaa toisin merkiten

Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI)

Lisää pysähtymisaiheisia ongelmia

Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI)

Groovy. Samuli Haverinen, Aki Hänninen. 19. marraskuuta 2015

11.4. Context-free kielet 1 / 17

Groovy. Niko Jäntti Jesper Haapalinna Group 31

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Transkriptio:

TIES542 kevät 2009 Tyyppiteorian alkeet Antti-Juhani Kaijanaho 9. helmikuuta 2009 [Staattinen t]yyppijärjestelmä on ratkeava, kieliopillinen menetelmä, jota käytetään todistamaan tiettyjen käytösten puuttuminen ohjelmasta luokittelemalla ilmaisuja niiden laskemien arvojen laadun perusteella. Benjamin C. Pierce (2002, sivu 1) Käsitteellä tyyppi (engl. type) on ohjelmointikielten alueella kaksi toisiinsa liittyvää merkitystä: Tyyppi määrittelee, mitä operaatioita johonkin arvoon taikka muistipaikkaan voidaan kohdistaa. Tyyppi määrittelee, miten jonkin olion tila (joka on pohjimmiltaan bittijono) tulkitaan arvoksi. Esimerkiksi kokonaislukuun voidaan kohdistaa aritmeettisia operaatioita mutta ei esimerkiksi aliohjelmana kutsumista toisaalta monien kielten kokonaislukutyyppinen muistialue tulkitaan luvuksi käyttäen kahden komplementti -esitystä. Tyyppivirhe (engl. type error) tarkoittaa tilannetta, jossa ohjelman suorituksen aikana yritetään kohdistaa johonkin arvoon taikka muistipaikkaan sellaista operaatiota, joka ei ole sen tyypin mukaan sallittua. Hyvä esimerkki useimmissa kielissä tyyppivirheestä on kokonaisluvun kutsuminen ikään kuin se olisi funktio. Tärkeää on kuitenkin huomata, että tyyppivirheen määritelmä riippuu kielestä (esimerkiksi ei ole mahdotonta kuvitella kieltä, joka määrittelee kokonaisluvulle myös funktiomerkityksen). Ohjelmointikieli voi ottaa tyyppeihin kantaa kahdella dimensiolla: olematon heikko vahva: Ohjelmointikieli on vahvasti tyypitetty, jos se diagnosoi kaikki tyyppivirheet; heikosti tyypitetty, jos se diagnosoi osan tyyppivirheistä; ja tyypitön, jos se ei diagnosoi yhtään tyyppivirhettä. 1

Huomaa, että tämä dimensio on osittainjärjestetty: kieli voi olla vahvemmin tyypitetty kuin toinen, vaikka kumpikaan ei olisi vahvasti tyypitetty. staattinen dynaaminen: Ohjelmointikieli on staattisesti tyypitetty, jos se diagnosoi tyyppivirheet (tai osan niistä) ennen suorituksen alkua, esimerkiksi käännösaikana; ja dynaamisesti tyypitetty, jos se diagnosoi tyyppivirheet (tai osan niistä) suorituksen aikana, tyypillisesti silloin, kun tyyppivirheellistä operaatiota ryhdytään yrittämään suorittaa. Kieli voi toki olla molempia. Tyyppivirheen diagnosointi tarkoittaa, että kielen toteutus estää kyseisen virheen sisältävän konstruktion suorittamisen ja antaa virheestä ohjelmoijalle (tai loppukäyttäjälle) palautetta. Esimerkki 1. Symboliset konekielet ovat (pääsääntöisesti) tyypittömiä. C on staattisesti heikosti tyypitetty ja dynaamisesti tyypitön kieli. C++ on C:tä vahvemmin tyypitetty sekä staattisesti että dynaamisesti. Java on C++:aa vahvemmin tyypitetty sekä staattisesti että dynaamisesti. Python ja Perl ovat staattisesti tyypittömiä ja dynaamisesti vahvasti tyypitettyjä kieliä. Haskell 98 (ilman laajennoksia) on staattisesti vahvasti tyypitetty. Ohjelmointikielen tyypitys on aina kompromissi tyyppiturvallisuuden ja ilmaisuvoiman välillä. Jokainen tyyppivirhe on useimmissa ohjelmissa aidosti ongelma, mutta on ohjelmia (erityisesti käyttöjärjestelmätasolla), joissa tyyppivirhe on tarkoituksellinen ja tarpeellinen. Mikäli kielen tyypitys on ilmaisuvoimaltaan heikkoa, voi aivan tavallistenkin ohjelmointiongelmien ratkaiseminen luonnollisella tavalla olla mahdotonta. Tässä monisteessa tarkastellaan tyyppiteoriaa, jossa on kyse nimenomaan staattisen tyyppijärjestelmän teoriasta. Alan tutkimuksen päätavoite on löytää vahvoja tyyppijärjestelmiä, jotka hylkäävät tyyppivirheinä yhä vähemmän käyttökelpoisia ohjelmointikonstruktioita. Täydellinen tyyppijärjestelmä on matemaattinen mahdottomuus, mutta täydellisyyttä voidaan lähestyä rajatta. Aiheen peruskirjallisuutta ovat Cardelli (2004) ja Pierce (2002). 1 Tyypitetty while-kieli Aiemmassa monisteessa määriteltiin while-kieli: siinä oli aritmeettiset lausekkeet ja ehtolausekkeet, sijoituslause, peräkkäistys, valintalause ja while-silmukka. Yksi 2

ikävä puute kielessä oli: muuttujaan ei voinut sijoittaa testin tulosta. Korjataanpa tämä ongelma. Jos muuttujaan voi sijoittaa testin tuloksen, pitää ratkaista, mitä tapahtuu, jos tällaisen muuttujan arvon antaa aritmeettiselle operaatiolle. Vastaavasti pitää sallia muuttujan käyttäminen suoraan testinä ja niinpä pitää ratkaista, mitä tapahtuu, jos lukuarvoista muuttujaa käytetään testinä. Joissakin kielissä tämä ratkaistaan siten, että testit ovat lukuja, ja nolla tarkoittaa epätotta. Tällä kertaa ei tehdä tuota ratkaisua, vaan pidetään luvut ja ehdot erillään. Määritellään, että kielessä on kaksi tyyppiä, luvut ja ehdot: T, U Types T, U ::= num bool Kielen syntaksissa ei enää erotella toisistaan luku- ja ehtolausekkeita. c N x, y, z Var e, f, g Expr e, f, g ::= c x e e + f e f e f e = f e f e < f e f e > f e f e f e f s, t Stmt s, t ::= x e s ; t if e then s else t while e do s Lausekkeiden staattinen tyyppijärjestelmä tavallisesti määritellään päättelyjärjestelmänä (vrt. lyhytaskelsemantiikka), jossa pääteltävänä on relaatio Γ e : T, missä 3

Γ: Var Types on osittaisfunktio muuttujilta tyypeille, ns. tyyppiympäristö (engl. type environment); e on jokin lauseke; ja T on jokin tyyppi. Relaatio Γ e : T luetaan Jos muuttujilla on ne tyypit, mitkä on Γ:ssa annettu, niin e:n tyyppi on T. Aritmeettisten operaattoreiden tyyppisäännöt ovat yksinkertaiset: operandien tulee olla lukuja ja tulos on luku: Γ e : num Γ e : num Γ e + f : num Γ e f : num Γ e f : num Vertailuoperaattoreillakin tilanne on yksinkertainen: (T-neg) (T-add) (T-sub) (T-mul) Γ e = f : bool Γ e f : bool Γ e < f : bool Γ e f : bool Γ e > f : bool Γ e f : bool (T-eq) (T-noteq) (T-lt) (T-le) (T-gt) (T-ge) Samoin loogiset operaattorit: Γ e : bool Γ f : bool Γ e f : bool Γ e : bool Γ f : bool Γ e f : bool (T-and) (T-or) 4

Kaikista yksinkertaisin tilanne on vakioilla: Γ c : num (T-const) Muuttujan kohdalla joudutaan tekemään hieman lisää työtä, sillä muuttujan tyyppi täytyy etsiä tyyppiympäristöstä. Tässä yhteydessä merkintätapa Γ, x : T tarkoittaa tyyppiympäristöä, jossa x:n tyyppi on T ja joka muuten on Γ 1 : Γ, x : T x : T (T-var) Lauseiden tapaukesssa tyypitysrelaatio on Γ s jos muuttujien tyypit ovat kuten Γ:ssa, niin s on hyvin tyypitetty lause. Γ, x : T e : T Γ, x : T x e Γ s Γ t Γ s ; t Γ e : bool Γ s Γ t Γ if e then s else t Γ e : bool Γ s Γ while e do s (T-ass) (T-seq) (T-if) (T-while) Tyyppijärjestelmän soveltaminen tapahtuu rakentamalla päättelypuita: x: num x : num x: num 1 : num x: num x : num x: num 0 : num x: num x 1 : num x: num x 0 : bool x: num x x 1 x: num while x 0 do x x 1 Jokaiseen puun vaakaviivaan liittyy jokin yllä annetuista säännöistä (esimerkiksi alimmassa on sovellettu T-whileä). Tehtävä 1. Merkitse näkyviin, mitä sääntöä kussakin vaakaviivassa on edellä sovellettu. Yllä kuvattu while-kielen tyyppijärjestelmä on ratkeava (engl. decidable), sillä jokaisessa säännössä viivan yläpuolella on pienempiä tehtäviä kuin viivan alapuolella; ja kielioppiohjautunut (engl. syntax-directed), sillä jokaiselle (abstraktin) kieliopin produktiolle on oma sääntönsä. 1. Eli Γ, x : T = Γ {(x, T ). 5

Nämä kaksi ominaisuutta tarkoittaa, että säännöstö on suhteellisen helppo kääntää tyyppitarkastusohjelmaksi. Kumpikin tyypitysrelaatio lausekkeiden Γ e : T ja lauseiden Γ s kääntyy omaksi aliohjelmakseen, jossa kukin ylläoleva sääntö tulee yhdeksi tapaukseksi. 2 Yksinkertaisesti tyypitetty lambda-kieli Aiemmassa monisteessa käsitelty lambda-kieli on tyyppiteorian arkkikieli: pääosa teoreettisista tyyppijärjestelmistä on rakennettu lambda-kielen päälle. Syy tähän lienee enimmälti historiallinen, mutta on myös niin, että lambda-kieli toimii varsin mainiosti eräänlaisena kaikkien ohjelmointikielten äitinä. Tyyppiteorian perusteoria on ns. yksinkertaisesti tyypitetty (engl. simply typed) lambda-kieli Λ, joka määritellään seuraavasti: x, y, z Var T, U Types T, U ::= T U t, u Λ t, u ::= x tu λx: T. t Vapaat muuttujat F V, korvausoperaattori [ := ] sekä α-ekivivalenssi ja β- sievennys määritellään samaan tapaan kuin tyypittömässä lambda-kielessä. Tyyppisäännöt ovat seuraavat: Γ, x : T x : T Γ t : U T Γ u : U Γ tu : T Γ, x : T t : U Γ (λx : T. t) : T U Huomaa, kuinka funktion parametrille on annettu tyyppi, ja huomaa, kuinka abstraktiotermin tyypityksesä parametrille annettua tyyppiä käytetään abstraktion rungon tyypityksessä laajentaen tyyppiympäristöä. 6

/ Types / enum type { T_NONE / signals type error /, T_BOOL, T_NUM ; / Expressions / enum exp_kind { E_CONST, / constants / E_VAR, / variables / E_NEG, / e / E_ADD, / e+f / E_SUB, / e f / E_MUL, / e f / E_EQ, / e = f / E_NQ, / e!= f / E_LT, / e < f / E_LE, / e >= f / E_GT, / e > f / E_GE, / e >= f / E_LAND, / e && f / E_LOR / e f / ; struct exp { enum exp_kind kind; union { char variable; / E_CONST / long constant; / E_VAR / struct exp unary_operand; / E_NEG / struct { struct exp left ; struct exp right; binary_operands; / the rest / u; ; / Statements / enum stmt_kind { S_ASSIGN, S_SEQ, S_IF, S_WHILE ; struct stmt { enum stmt_kind kind; union { struct { char x; struct exp e; assign ; struct { struct stmt left ; struct stmt right; seq; struct { struct exp test; struct stmt if_true; struct stmt if_false; if_; struct { struct exp test; struct stmt body; 7

/ Typecheck expressions; type error is returned as T_NONE / enum type tc_exp(struct type_env env, struct exp e) { switch (e >kind) { case E_CONST: return T_NUM; case E_VAR: { enum type ty = lookup_var(env, e >u.variable); if (ty == T_NONE) { fprintf ( stderr, "undefined variable %s \n", e >u.variable); return ty; case E_NEG: if (tc_exp(env, e >u.unary_operand)!= T_NUM) { fprintf ( stderr, "type error in negation\n"); return T_NONE; return T_NUM; case E_ADD: case E_SUB: case E_MUL: if (tc_exp(env, e >u.binary_operands.left)!= T_NUM tc_exp(env, e >u.binary_operands.right)!= T_NUM) { fprintf ( stderr, "type error in arithmetic\n"); return T_NONE; return T_NUM; case E_EQ: case E_NQ: case E_LT: case E_LE: case E_GT: case E_GE: if (tc_exp(env, e >u.binary_operands.left)!= T_NUM tc_exp(env, e >u.binary_operands.right)!= T_NUM) { fprintf ( stderr, "type error in comparison\n"); return T_NONE; return T_BOOL; case E_LAND: case E_LOR: if (tc_exp(env, e >u.binary_operands.left)!= T_BOOL tc_exp(env, e >u.binary_operands.right)!= T_BOOL) { fprintf ( stderr, "type error in comparison\n"); return T_NONE; return T_BOOL; / not reached / abort(); Listing 2: Tyyppitarkastusta C:llä, osa 2 8

/ Typecheck statements; returns nonzero if no type errors. / int tc_stmt(struct type_env env, struct stmt s) { switch (s >kind) { case S_ASSIGN: if (tc_exp(env, s >u.assign.e)!= lookup_var(env,s >u.assign.x)) { fprintf ( stderr, "type error in assignment\n"); return 0; return 1; case S_SEQ: return tc_stmt(env, s >u.seq.left) && tc_stmt(env, s >u.seq.right); case S_IF: if (tc_exp(env, s >u.if_.test)!= T_BOOL) { fprintf ( stderr, "a test must be boolean\n"); return 0; return tc_stmt(env, s >u.if_.if_true) && tc_stmt(env, s >u.if_.if_false); case S_WHILE: if (tc_exp(env, s >u.while_.test)!= T_BOOL) { fprintf ( stderr, "a test must be boolean\n"); return 0; return tc_stmt(env, s >u.while_.body); / not reached / abort(); Listing 3: Tyyppitarkastusta C:llä, osa 3 9

Tällä tavalla määritelty yksinkertaisten tyyppien lambda-kieli on sinänsä täysin typerä, sillä yhtään tyyppiä ei ole määritelty! Senpä takia toisin kuin tyypittömässä lambda-kielessä pitää aina määritellä joitakin perustyyppejä, esimerkiksi luvut: c Z x, y, z Var T, U Types T, U ::= T U Num t, u Λ Num t, u ::= x tu λx: T. t c t t + u t u t u Vapaat muuttujat F V, korvausoperaattori [ := ] sekä α-ekivivalenssi määritellään samaan tapaan kuin tyypittömässä lambda-kielessä. Laskentasääntö ( ) on β-sievennyksen yleistys ja sisältää myös aritmetiikan laskemisen. Tyyppisäännöt ovat seuraavat: Γ, x : T x : T Γ t : U T Γ u : U Γ tu : T Γ, x : T t : U Γ (λx : T. t) : T U Γ c : Num Γ t : Num Γ t : Num Γ t : Num Γ u : Num Γ t + u : Num Γ t : Num Γ u : Num Γ t u : Num 10

Γ t : Num Γ u : Num Γ t u : Num Tässä kielessä f(x) = x + 1 kirjoitettaisiin λx : Num. x + 1. Viitteet Luca Cardelli. Type systems. In Allen B. Tucker, editor, CRC Handbook of Computer Science and Engineering. CRC, 2 edition, 2004. Benjamin C. Pierce. Type and Programming Languages. MIT Press, Cambridge, MA, 2002. 11