5.2.5 Konstruktoriluokat Edellisessä esimerkissä määrittelimme oman tyyppiluokan Isqrt jonka jäsenet olivat tyyppejä (kuten Int, Integer, Word,...).

Koko: px
Aloita esitys sivulta:

Download "5.2.5 Konstruktoriluokat Edellisessä esimerkissä määrittelimme oman tyyppiluokan Isqrt jonka jäsenet olivat tyyppejä (kuten Int, Integer, Word,...)."

Transkriptio

1 5.2.5 Konstruktoriluokat Edellisessä esimerkissä määrittelimme oman tyyppiluokan Isqrt jonka jäsenet olivat tyyppejä (kuten Int, Integer, Word,...). Voimme määritellä tyyppiluokkia myös tyyppikonstruktoreille eli niille joilla on tyyppiparametreja. Sellaista luokkaa kutsutaan konstruktoriluokaksi (constructor class). Esimerkiksi hakupuumme ovat yksi esimerkki tietorakenteen sanakirja toteutuksesta. Millainen olisi yleensä luokka sellaiset s joita voi käyttää sanakirjana? Siis tämä s on nyt tyyppikonstruktori, jolla on kaksi tyyppiargumenttia: s k t on tyyppi, jossa k on sanakirjan avainten ja t kuhunkin avaimeen liittyvän tieokentän tyyppi. Tällöin määrittelemme tyyppiluokan jonka tyyppiparametrina on tämä s ilman parametrejaan metodeina on ne operaatiot, jotka haluamme sanakirjalla s k t olevan. Näiden metodien tyypeissä tällä s on siis ne kaksi parametriaan, ja täällä ilmaisemme niiden rajoitteet. Voimme vaatia sanakirjalta seuraavat operaatiot: luonti listasta (avain,tieto)-pareja metodilla fromlist muunnos takaisin tällaiseksi listaksi metodilla intolist haku annetulla avain arvolla metodilla lookfrom. Laitamme luonti- ja hakumetodien tyyppeihin rajoitteen että avain tyypin pitää olla järjestetty. Sellaisen yksi mahdollinen instanssi on siis s = Puumme: Meillä on sopiva toteutus jokaisellä näistä kolmesta metodista. import Data.List class Dictionary s where lookfrom :: (Ord k) => k -> s k t -> Maybe t fromlist :: (Ord k) => [(k,t)] -> s k t intolist :: s k t -> [(k,t)] {- Hakupuumme ovat yksi sanakirjatyyppi. -} instance Dictionary Puu where 86

2 fromlist = listasta intolist = listaksi lookfrom = undefined -- harjoitustehtävä data Puu k t = Tyhja Solmu (Puu k t) k t (Puu k t) deriving (Show) lisaa :: (Ord k) => k -> t -> Puu k t -> Puu k t lisaa x y Tyhja = Solmu Tyhja x y Tyhja lisaa x y haara@(solmu vasen avain tieto oikea) x < avain = Solmu (lisaa x y vasen) avain tieto oikea x > avain = Solmu vasen avain tieto (lisaa x y oikea) otherwise = haara listasta :: (Ord k) => [(k,t)] -> Puu k t listasta = foldr (uncurry lisaa) Tyhja listaksi :: Puu k t -> [(k,t)] listaksi = let listaksia Tyhja a = a listaksia (Solmu vasen avain tieto oikea) a = listaksia vasen $ (avain,tieto) : listaksia oikea a in flip listaksia [] {- Toinen sanakirjatyyppi on lista (avain,tieto)-pareja. -} newtype DictList u v = DictList { dictlist :: [(u,v)] } deriving (Show) instance Dictionary DictList where lookfrom x = lookup x. dictlist fromlist = DictList intolist = dictlist Toinen mahdollisuus tällaiseksi sanakirjatyypiksi s on lista (avain,tieto)-pareja. Määritellään se uudeksi tyypiksi DictList joka on haluttua muotoa: tyyppikonstruktori jolla on kaksi tyyppiparametria. Näin Dictionarystä tulee rajapinta, jonka voi toteuttaa monella eri tyypillä. 87

3 Kun muu koodi käyttää tätä rajapintaa eikä juuri jonkin tietyn sanakirjaksi sopivan tyypin omia funktioita, niin sanakirjatoteutuksen vaihtaminen toiseen on vaivattomampaa. Moniparametrisista konstruktoriluokista Edellinen sanakirjaesimerkkimme herättää välittömästi kysymyksen: Miksi emme määritelleet tyyppiluokkaamme suoraan siten, että sillä voisi olla monta parametria? Eli miksi emme aloittaneetkaan tyyppiluokkamme määrittelyä class Sanakirja s k t where joka tarkoittaisi suoraan että s on sellaisten sanakirjojen tyyppi, joiden avaimet ovat tyyppiä k ja tietokentät tyyppiä t. Yksiparametriset tyyppiluokat sanovat että tämä tyyppi kuuluu tuohon tyyppikokoelmaan.... Tällainen moniparametrinen (multiparameter) tyyppiluokka sanookin yleisemmin näillä tyypeillä on yhdessä sellainen ominaisuus että.... Tällaiset moniparametriset tyyppiluokat tulevatkin hyvin hyödyllisiksi kun tyyppejä alkaa käyttää mutkikkaammin kuin tällä kurssilla teemme. Niinpä ne ovatkin Haskell-yhteisössä kiivaan tutkimus- ja kehitystyön aihe. Haskell standardiin niitä ei kuitenkaan ole vielä otettu, koska yhteisössä ei vielä vallitse yksimielisyys siitä, miten ne tarkkaan ottaen pitäisi määritellä ja toteuttaa. Erityisen hankalaksi on osoittautunut se, miten näiden tyyppien väliset mahdolliset riippuvuudet pitäisi ilmaista. Miten esimerkiksi kätevimmin ilmaistaisiin että jos avaintyyppi k on tämän lainen, niin sitä vastaavaksi sanakirjatyypiksi s pitääkin valita tuon lainen, jne.? Tällaisilla riippuvuuksilla voisi sitten ilmaista samantapaisia tyyppien välisiä suhteita kuin vaikkapa Javan sisäluokilla (inner classes) sekä paljon muuta... Aiemmin tähän on ehdotettu ns. funktionaalisia riippuvuuksia (functional dependencies). Uudempi ehdotus ovat tyyppiperheet (type families). Tulkki ghci sisältää laajennuksinaan nämä molemmat ehdotukset. Oletusarvoisesti ghci käynnistyy Haskell 98 -standardin mukaisena, jos se on versiota 6 Haskell standardin mukaisena, jos versiota 7. 88

4 Tästä standardista pääsee tällaisiin laajennuksiin esimerkiksi aloittamalla lähdekooditiedostonsa erikoisella kommentilla {-# OPTIONS_GHC -fglasgow-exts #-} joka kertoo Glasgow Haskell Compilerille että tässä lähdekooditiedostossa käytetään kaikkia sen omia laajennuksia. Sopivilla optioilla -X... on mahdollista ilmoittaa tarkemmin, mitkä kaikista laajennuksista haluaa ottaa käyttöön. Näistä laajennuksista kiinnostuneet voivat tutustua niihin omin neuvoin; tämä kurssi pysyttelee standardissa. Tyyppijärjestelmän muita laajennuksia ovat esimerkiksi: Yleistetyt algebralliset tietotyypit (Generalized ADTs, GADTs) joiden datatyyppimäärittelyissä ohjelmoija voi antaa konstruktoreilleen tarkemman tyypin kuin minkä Haskell antaisi. Eksplisiittinen tyyppikvanttori forall. Haskellissä on näkymätön eli implisiittinen tyyppikvanttori: Jos tyypissä esiintyy muuttuja kuten a, niin se tarkoittaa mikä tahansa tyyppi (mahdollisin rajoittein). Tämän voi ilmaista myös näkyvästi eli eksplisiittisesti muodossa jokaisella tyypillä a (jolla)... Sillä voi ilmaista mutkikkaampiakin tyyppejä kuin hiljaisella esimerkiksi että on olemassa jokin tyyppi b (jolla)... joka tuo entistä enemmän olio-ohjelmoinnin piirteitä Haskell-ohjelmointiin. Tyyppijärjestelmä onkin se osa Haskellia, jota kehitetään tutkimuksessa voimakkaimmin sitähän voi aina kehittää yhä ilmaisuvoimaisemmaksi Valmiiksi määritellyistä konstruktoriluokista Prelude määrittelee erityisesti seuraavat kaksi yksiparametrista konstruktoriluokkaa Funktorit johon kuuluvilla tyyppikonstruktoreilla m on sellainen yhteinen ominaisuus, että niille on mielekästä määritellä korkeamman kertaluvun operaatio sovella tätä funktiota f jokaiseen alkioon x minun sisälläni ja kokoa nämä yksittäiset tulokset f(x). Monadit johon kuuluvilla tyyppikonstruktoreilla m taas on sellainen yhteinen ominaisuus, että niille on mielekästä määritellä sama operaatio mutta siten, että jokainen f(x) onkin jokin kokoelma tuloksia ja ne kaikki kootaan yhteen. Monadeilla on monia muitakin tulkintoja ja käyttökohteita! Funktorit ja monadit ovat kotoisin matematiikan haarasta nimeltään kategoriateoria (category theory). Erityisesti karteesisesti suljetut kategoriat (Cartesian Closed Categories, CCC) ovat matemaattinen malli Churchin λ-laskennalle......ja sitä kautta siis myös funktionaaliselle ohjelmoinnille. CCC:t antavat siis funktionaaliselle ohjelmoinnille taustateorian samaan tapaan kuin Turingin koneet antavat sellaisen tilaperustaiselle ohjelmoinnille. 89

5 Funktorit Mutta CCC:t siis tekevätkin sen puhtaassa matematiikassa vetoamatta mihinkään laskulaitteisiin. Termi karteesinen tarkoittaa, että näissä kategorioissa on karteesiset tulot eli parit. Kategoriset konstruktiot voi kääntää toisinpäin. Kun parien konstruktio käännetään toisinpäin, niin saadaan summat. Nämä summat vastaavat Preluden tyyppejä data Either a b = Left a Right b deriving (Eq, Ord, Read, Show) Termi suljettu taas tarkoittaa, että nämä kategoriat sisältävät kaikki ne funktiot, jotka voi määritellä näiden konstruktioiden pohjalta. Haskell-standardi määrittelee siis konstruktoriluokan class Functor m where fmap :: (a -> b) -> m a -> m b jossa m on siis yksiparametrinen tyyppikonstruktori. Sen instancet ilmaisevat, että seuraavat kaksi järkevyysehtoa pätevät: identiteettikuvaukselle id x = x ja yhdistetylle kuvaukselle f g. fmap id = id (8) fmap (f. g) = fmap f. fmap g (9) Jos esimerkiksi tämä m olisi matematiikan joukko, niin silloin nämä ehdot (8) ja (9) saataisiin pätemään valitsemalla fmap f S = {f(x): x S}. Esimerkiksi listoille samat saa pätemään Preluden instance Functor [] where fmap = map jossa [] on yksiparametrisen tyyppikonstruktorin [u] nimi ilman syntaktista sokerointia map todellakin täyttää nämä kaksi ehtoa listan voi tulkia joukon sijaan luetteloksi alkiota. Toinen esimerkki Preludesta on instance Functor Maybe where fmap f Nothing = Nothing fmap f (Just x) = Just (f x) jossa taas tyypin Maybe a voi tulkita tarkoittavan 0- tai 1-alkioista joukkoa tai listaa. 90

6 Monadit Haskell-standardi määrittelee myös konstruktoriluokan class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a m >> k = m >>= \_ -> k fail s = error s jossa m on siis yksiparametrinen tyyppikonstruktori. Vertaamalla funktioiden (>>=) ja flip fmap korkeamman kertaluvun f parametrin tyyppejä huomaa yhteyden: funktoreissa f palauttaa arvon tyyppiä b monadeissa taas tyyppiä m b. Toinen keskeinen funktio return taas tekee yhdestä yksittäisestä arvosta kokoelman. Monadin instance on lupaus, että seuraavat järkevyysehdot eli monadilait (monadic laws) pätevät: return a >>= k = k a (10) m >>= return = m (11) m >>= (\ x -> k x >>= h) = (m >>= k) >>= h (12) ja jos lisäksi pätee myös Functor m niin silloin myös ne yhdistävän lisäehdon pitää päteä. fmap f xs = xs >>= return. f (13) Jos tämä m olisi matematiikan joukko niin silloin nämä monadilait tulisivat voimaan valitsemalla return x = {x} S >>= f = x S f(x). Esimerkkejä sellaisista instansseista Preludessa ovat instance Monad Maybe where (Just x) >>= k = k x Nothing >>= k = Nothing return = Just fail s = Nothing instance Monad [] where m >>= k = concat (map k m) return x = [x] fail s = [] 91

7 joissa toistuu sama idea 0/1-alkioisille ja yleisille luetteloille. Kun Haskell-ohjelmaa ei käytetä tulkissa vaan se on käännetty itsenäiseksi suorituskelpoiseksi koodiksi, niin silloin sen yhteydenpito ympäristönsä kanssa (eli syötteiden lukeminen ja tulosteiden kirjoittaminen, jne.) on mallinnettu matemaattisesti tällaisena monadina. Ohjelmoijalle tarjotaan (onneksi!) do-notaatio syntaktisena sokerina monadisen koodin kirjoittamisen helpottamiseksi. Tätä vaihtoehtoista proseduraalista notaatiota voikin käyttää kaikilla monadeilla, ei vain I/O-monadissa. Saman kaltainen monadinen mallinnus on alkanut nousta esille myös esimerkiksi tiedonhallinnassa. Perinteinen relaatiotietomalli ja SQL-kyselykieli pohjautuvat logiikkaan ja ns. relaatioalgebraan. Monadien pohjalta taas voi kehittää niille vaihtoehtoisia tietomalleja ja kyselykieliä: Olkoon m a jokin a-tyyppisten tietojen varasto... Ne taas ovat kiinnostavia esimerkiksi Web-hakukoneiden tiedonhallinnassa, jota edustaa esimerkiksi edellä mainittu Googlen MapReduce: Funktorit ja monadit tyypittävät sellaisten järkeviä operaatioita. 92

8 6 Modulit Haskell-kielessä on yksinkertainen modulijärjestelmä. Moduleilla ilmaistaan, mitkä ohjelman yhdessä osassa määritellyt funktiot, tyypit ja tyyppiluokat ovat paikallisia eli käytettävissä vain tässä samassa osassa julkisia eli käytettävissä kaikissa muissakin osissa, jos nämä muut osat niin haluavat. Jos eri ohjelmointikielten modulijärjestelmät alkavat kiinnostaa, niin kannattaa tutustua Standard ML (SML) -kielen järjestelmään se on hyvin kehittynyt. Jos Haskell-lähdekooditiedosto on oma modulinsa, niin silloin se alkaa seuraavasti: module Hierarkinen.Modulin.Nimi(viennit) where tuonnit. jonka jälkeen tulevat Haskell-esittelyt ja -määrittelyt. Tulkki ghci olettaa näin otsikon modulin löytyvän tiedostosta nimeltä Tuonnit Linuxissa Hierarkinen/Modulin/Nimi.hs Windowsissa hierarkinen\modulin\nimi.hs jonka polku alkaa nykyisestä työhakemistosta josta ohjelmoija voi siis aloittaa tämän nyt tekeillä olevan ohjelman oma moduli- ja tiedostohierarkia tulkin asennuksen yhteydessä määritellystä pakkaushakemistosta josta alkaen se löytää vakiokirjastonsa kuten Data.Word jne. muista hakemistoista joita voi antaa tulkille optioina joko komentorivillä tai lähdekooditiedoston erikoiskommentissa {-# OPTIONS_GHC... #-} Ainakin Linuxissa sen voi asettaa myös työhakemistokohtaisessa alustustiedostossa./.ghci tai käyttäjäkohtaisessa alustustiedostossa ~/.ghci. Modulin tuonnit koostuvat tuontilauseista jollaisen perusmuoto on import Toinen.Hierarkinen jota olemmekin jo käyttäneet omissa lähdekooditiedostoissamme. 93

9 Jos jokin nimi esiintyy modulin nimeltään Toinen.Hierarkinen otsikon kohdassa viennit niin silloin tähän moduliin ilmestyvät sen lyhyt nimi eli pelkkä nimi sekä sen pitkä nimi eli Toinen.Hierarkinen.nimi. Haskell sallii sen, että samassa modulissa on monelle eri asialle sama nimi tuontien seurauksena. Mutta jos ohjelmassa yrittää käyttää tällaista moneen eri kertaan määriteltyä nimeä, niin silloin saakin virheilmoituksen. Niiden erottamiseksi toisistaan importin ja modulin nimen väliin voi lisätä määreen qualified jolloin tähän moduliin tulevat sieltä vain pitkät nimet Toinen.Hierarkinen.nimi. Koska tällaisten nimien kirjoitusasut voivat tulla pitkiksi, niin modulin nimen jälkeen voi lisätä määreen as Lyhenne jolloin nämä pitkät nimet kirjoitetaankin muodossa Lyhenne.nimi. Esimerkiksi tulkin ghci mukana tulee kirjasto, joka toteutta tietorakenteen joukko. Koska osa sen nimistä on samoja kuin Preludessa niin se tuodaan tavallisesti muodossa import qualified Data.Set as Set jotta esimerkiksi Preluden funktio null ja kirjaston funktio Set.null pysyvät erillään. Jos haluaa tuoda modulista vain joitakin sen nimi stä niin ne voidaan listata suluissa pilkuin, eroteltuna koko importin lopussa. Jos haluaakin tuoda modulin nimi stä kaikki muut paitsi näitä listattuja, niin silloin tämän listan eteen voi lisätä määreen hiding Siten tuontilause kaikilla näillä optioilla on import qualified Toinen.Hierarkinen as Lyhenne hiding (nimi 1,nimi 2,nimi 3,...,nimi k ) 94

10 Viennit Modulin viennit ovat pilkuin, eroteltu lista siinä itsessään tunnettuja alkio ita ne jotka tämä moduli tarjoaa muiden modulieen tuotaviksi pitkinä niminään Hierarkinen.Modulin.Nimi.alkio. Tällaisen alkion yksinkertaisin muoto on funktion nimi: Silloin tämä moduli siis sallii muiden modulien käyttävän tätä funktiota. Toinen alkion muoto on module Toinen.Hierarkinen jollekin tämän modulin itseensä tuomista moduleista. Silloin tämä moduli myös vie sen ne osat, jotka se toikin itseensä. Jos tämän modulin käyttö vaatii että myös tuo Toinen.Hierarkinen moduli on käytössä, sen käyttäjät selviävät yhdellä importilla kahden sijasta. Kolmas alkion muoto on TyyppiLuokanNimi(metodit) jossa metodit ovat lista pilkuin, eroteltuja sen metodien nimiä, jotka siis viedään joita voi siis kuormittaa tämän luokan uusia instansseja määritellessä.. joka on lyhennemerkintä sen kaikkien metodien lista poissa jolloin myös turhat sulutkin () voidaan jättää pois. Silloin viedään vain tämän luokan nimi mutta ei ainoatakaan sen metodeista. Silloin tätä luokkaa voi käyttää rajoitteissa mutta sille ei voi lisätä uusia instansseja koska sen metodeja ei voi kuormittaa, koska niitä ei vietä tästä modulista. Kaikki tässä modulissa määritellyt eri tyyppiluokkien instanssit viedään siitä ulos automaattisesti ilman eri mainintaa, ja siten myös tuodaan jokaiseen moduliin joka tuo mitään tästä modulista. Tämä takaa sen, että koko ohjelmassa on vain yksi tapa määritellä tietty instanssi. Modulin otsikosta voi jättää pois kaikki viennit sekä turhat sulutkin (): Sellainen moduli vie muihin moduleihin kaiken muun sisältönsä paitsi importit. 95

11 6.1 Abstraktit tietotyypit Neljäs alkion muoto on TyypinNimi(konstruktorit) jossa tyyppiluokkien tapaan konstruktorit ovat lista pilkuin, eroteltuja sen konstruktoreiden nimiä jotka siis viedään joita voi siis käyttää muisaakin moduleissa.. joka on lyhennemerkintä sen kaikkien konstruktoreiden lista poissa jolloin myös turhat sulutkin () voidaan jättää pois. Silloin viedään vain tämä tyyppi mutta ei ainoatakaan sen konstruktoreista. Jos tyypissä on käytetty kentännimiä, ja ne haluaan viedä, niin ne voi laittaa joko tähän samaan listaan kuin sen konstruktoritkin tai omina alkioinaan. Modulaarisessa ohjelmoinnissa puhutaan paljon abstrakteista tietotyypeistä (Abstract Data Type, ADT): Tyyppi T on abstrakti, jos sen jos sen sisäinen rakenne ja toiminta on suojattu siten, ettei tyyppiä T käyttävä ohjelmakoodi pysy mitenkään ei vahingossa eikä tahallaan käsittelemään sen arvoja toisin kuin tyypin T ohjelmoija on tarkoittanut. Algebrallinen tietotyyppi T (josta myös käytetään samaa lyhennettä ADT...) on abstrakti, jos sitä käyttävä ohjelmakoodi ei pysty käyttämään sen konstruktoreita eikä kentännimiä. Siten Haskell-tyyppi T on abstrakti, jos sen määrittelevä moduli M mainitsee sen vientilistassaan pelkkänä alkiona T ilman sulkeita (...). Silloinhan tyyppiä T käyttävä ohjelmakoodi voi luoda sen arvoja ja tutkia niiden sisältöä vain niillä funktioilla, jotka tyypin T ohjelmoija on ohjelmoinut tähän moduliinsa M. Haskell-moduli toteuttaakin usein yhden abstraktin tietotyypin operaatioineen. Klassinen esimerkki abstraktista tietotyypistä on pino (pushdown stack) operaatioineen Luo tyhjä pino. Onko tämä pino tyhjä? Työnnä tämä alkio tuohon pinoon sen päällimmäiseksi. Ota tästä epätyhjästä pinosta sen päällimmäinen. 96

12 module Stack(Stack, empty, isempty, push, pop) where newtype Stack a = IntoStack{ fromstack :: [a] } empty :: Stack a empty = IntoStack [] isempty :: Stack a -> Bool isempty = null. fromstack push :: a -> Stack a -> Stack a push x = IntoStack. (x :). fromstack pop :: Stack a -> (a,stack a) pop (IntoStack (top:more)) = (top,intostack more) 6.2 Päämoduli Koko ohjelman päämoduli on poikkeus: Se saa olla minkä nimisessä tiedosto ssa tahansa (kunhan sen loppuliite on.hs). Sen nimi on aina Main. Sitä ei ole pakko otsikoida. Silloin sen otsikoksi oletetaan module Main(main) where jossa main on Haskell-pääohjelman standardoitu nimi. Jos päämodulin sisältävä tiedosto halutaan kääntää suorituskelpoiseksi ohjelmaksi, joka ei tarvitse tulkkia ghci, niin silloin käännöskomento riippuu kääntäjän ghc versiosta. Jos se on 6.x.y niin komento on ghc --make tiedosto jossa optio--make ohjaa kääntäjän käymään läpi kaikki importit ja kääntämään (uudelleen) kaiken mitä tarvitaan ohjelman kokoamiseksi 7.u.v niin optiota--make ei enää tarvitse mainita erikseen, vaan se on oletusarvona. 97

13 Tämän suorituskelpoisen ohjelman nimeksi tulee tiedosto ilman loppuliitettään.hs. 98

14 7 Monadit ja I/O Tämän Haskell-pääohjelman main tyypin pitää olla muotoa IO τ jossa IO on tyyppikonstruktori, jonka voi lukea sellainen laskenta jolla on lupa tehdä I/O- eli syöttö- ja tulostusoperaatioita (Input/Output) kun se muodostaa tulostaan, joka on tyyppiä... τ joka voi olla mikä tahansa tyyppi. Siis main :: IO τ on sellainen laskenta että jos joku sen käynnistäisi niin se kommunikoisi ulkomaailman kanssa muodostaessaan tuloksensa tyyppiä τ. Tässä siis tyyppikonstruktori IO ei välttämättä synnytäkään mitään tietokenttiä, joissa olisi tyypin τ arvoja vaan se voi synnyttää vaikkapa funktioita tyyppiä -> τ tms. Kenellä sitten on oikeus käynnistää tällainen laskenta joka kommunikoi ulkomaailman kanssa? Kääntäjän ghc tuottama koodi alkaa laskea mainin arvoa ja sen laskennan lopuksi hylkää saamansa arvon, joka siis oli tyyppiä τ... Useimmiten mainin tyyppinä τ onkin () eli ei mitään kiinnostavaa. Tulkissa ghci voi testailla tyyppiä IO τ olevia lausekkeita ja nähdä myös niiden tulokset. Mutta kenelläkään muulla ei ole oikeutta käynnistää tällaista laskentaa. Tämä saavutetaan sillä, että tyyppikonstruktori IO on täysin abstrakti, eikä sille ole tarjolla operaatiota aja tämä laskenta. Tämä takaa sen, että heti kun lausekkeen tulostyyppi on jotakin muuta kuin tämä IO τ niin se on puhdasta funktionaalista koodia, joka ei tee lainkaan I/O-operaatioita. Kuten jo aiemminkin mainittiin, niin tällaiset I/O-operaatiot ovat ongelmallisia puhtaassa funktionaalisessa ohjelmoinnissa: Syöttö kuten lue seuraava syöterivi ei ole funktio, koska eri kutsukerroilla on tarkoitus lukea eri rivit. Funktionhan pitää palauttaa aina saman arvon saadessaan samat parametrit. Tulostus kuten tulosta ruudulle teksti... taas vaikuttaa tarpeettomalta. Laiska laskentahan laskee välituloksen vain jos sitä tarvitaan lopputuloksen laskemiseen, ja tulostaminenhan ei tuota mitään mielenkiintoista välitulosta. Haskell siis ratkaisee tämän ongelman tyypittämällä maailmansa kahteen osaan: I/O-laskentaan jossa pääohjelma main ja sen kutsumat muut IO-tulostyyppiset funktiot voivat tehdä näitä I/O-operaatioita sekä tehdä kutsuja 99

15 puhtaisiin funktioihin, jotka voivat vain palauttaa arvojaan kutsujilleen mutta eivät itse voi tehdä mitään I/O-operaatioita. Haskell määrittelee tämä abstraktin tyyppikonstruktorinsa IO monadina. Sitä ei kuitenkaan tulkitakaan kokoelmana kuten aiemmin, vaan idea on nyt seuraava: Keskeisen monadioperaattorin tyyppi on nyt (>>=) :: (Monad IO) => IO a -> (a -> IO b) -> IO b Siis lausekkeessa p >>= f jälkimmäinen funktio f tarvitsee argumentikseen tyyppiä a olevan arvon. Edellinen lauseke p voi tuottaa sellaisen arvon funktiolle f mutta sen tuottaminen vaatii, että ensin pitää suorittaa lausekkeen p kuvaama laskenta. Siten IO onkin sellainen monadi, jonka operaattori (>>=) tarkoittaakin, että suorita ensin laskenta p ja valitse sitten funktiolla f sen tuloksen perusteella, millaisella laskennalla jatketaan siitä eteenpäin. Koska pääohjelma saa tyypin main :: IO () niin se sanoo että aloita laskenta pääohjelman alusta, ja jatka sitten näin askel askeleelta sen loppuun saakka, jotta saisit selville sen lopullisen (tarpeettoman) arvon. Näin tyyppikonstruktorin IO monadisuus antaa halutun I/O-askelluksen, vaikka laskenta onkin laiskaa. Katsotaan sitten tyyppiluokan Monad määritelmää tästä I/O-askelluksen näkökulmasta: Operaattori (>>) on operaattorin (>>=) sellainen erikoistapaus, jossa seuraava askel f ei riipu edellis(t)en tuloksesta. Esimerkiksi jos edellä tulostettiin eikä laskettukaan mitään kiinnostavaa arvoa. Toinen keskeinen funktio return muuntaa tavallisen arvon x laskennaksi joka tuottaa saman tuloksen x tekemättä I/O-operaatioita. Tavallisesti ohjelmointikielissä return x tarkoittaa että palaa tästä aliohjelmasta heti sen kutsujaan vastauksena x. Haskell on valinnut tämän saman nimen tälle muunnokselle, koska sen tavallisin (mutta ei ainoa!) käyttö on oleellisesti sama: Se esiintyy yleensä IO-tyyppisen lausekkeen lopussa, ja muuntaa sen laskeman vastauksen IO-tyyppiseksi. Erona kuitenkin on, että Haskellin return ei vaikuta askellukseen: Jos lauseke jatkuu returnin jälkeenkin, niin sen arvon laskenta etenee sinne loppuosaan. Katsotaan sitten monadilakeja (10) (13) tästä I/O-askelluksen näkökulmasta: (10) sanoo, että jos edellinen laskenta palauttaa tässä mielessä arvon a, niin seuraava askel k ottaa sen käyttöönsä. (11) taas sanoo, että jos edellinen laskenta on tuottanut jonkin arvon m ja seuraava askel on return niin silloin palautetaan tämä m tässä mielessä. 100

16 Nämä kaksi monadilakia siis ilmoittavat yhdessä sen, miten return toimii suhteessa operaattoriin (>>=). Niiden intuitio on, että return on operaattorin (>>=) eräänlainen neutraalialkio nyt kun kyseessä ovat funktiot. Toisin sanoen, return muuntaa arvon a sellaiseksi laskennaksi joka ei tee itse mitään se vain välittää arvon a laskennassa eteenpäin. (12) taas sanoo intuitiivisesti, että operaattori (>>=) on liitännäinen. Tämä näkyy selvemmin, jos lain ensimmäiseksi operaattoriksi vaihdetaankin (>>) jolloin x katoaa: m >> (k >>= h) = (m >> k) >>= h Siten (>>=)-operaattoreiden lauseketta ensimmäinen (>>=) toinen (>>=) kolmas (>>=) lasketaan askeltamalla järjestyksessä ensimmäisestä toiseen, toisesta kolmanteen,... riippumatta siitä, miten lausekkeen sulut ovat. (13) sanoo, että funktion fmap :: (a -> b) -> IO a -> IO b kutsu fmap f p tuottaa sellaisen laskennan joka 1. suorittaa ensin laskennan p 2. soveltaa sitten sen tulokseen funktiota f ja jatkaa näin saadulla arvolla. Siten Haskell-pääohjelma main ja kaikki sen kutsumat IO-tyyppiset funktiot, jotka suorittavat I/O-operaatioita, voitaisiin kirjoittaa (>>=)-lausekkeina. 7.1 do-syntaksi Tällaisten pitkien (>>=)-lausekkeiden kirjoittaminen tulisi kuitenkin kovin vaivalloiseksi, ja siksi Haskell tarjoaakin syntaktisena sokerina niille seuraavanlaisen syntaksin: do lause 1 lause 2 lause 3. lause q lauseke jonka lopussa oleva lauseke on tyyppiä M τ jossa tyyppikonstruktori M on jokin Monadi. Yleensä tämä lauseke on siis return x jossa arvon x tyyppi on τ. Pääohjelmassa main tämä M on siis IO. Tätä viimeistä lauseketta edeltävät lauseet voivat olla: 101

17 laskentakutsuja muotoa hahmo <- kutsuttava jossa kutsuttava lauseke on Monadista tyyppiä M µ ja hahmo sen alkiotyyppiä µ. 1. Ensin suoritetaan kutsuttavan lausekkeen määrittelemä laskenta. 2. Sitten sovitetaan sen tuottama arvo a tähän hahmoon. 3. Jos se sopii, niin tämänhahmon antamat nimet arvon a osille näkyvät tästä lause eesta alkaen tämän do-lausekkeen loppuun (ellei jokin myöhäisempi hahmo tai määrittely peitä niitä näkyvistä). 4. Jos se ei sovikaan, niin silloin kutsutaankin Monadin M metodia fail. Intuitiona on siis suorita tämä kutsuttava aliohjelma ja nimeä kutsun palauttama arvo a hahmolla. Tämä <- on siis se kohta, jossa do-notaatio sokeroi operaattorin (>>=) käytön. Jos palautusarvo a ei kiinnosta (esimerkiksi jos kutsuttava aliohjelma on jokin tulostusrutiini) niin silloin hahmo <- voidaan jättää poiskin tarpeettomana. Se puolestaan on kohta, jossa do-notaatio sokeroikin operaattorin (>>) käytön. Esimerkiksi z <- getline 1. kutsuu ensin vakiokirjaston I/O-aliohjelmaa lue seuraava syöterivi 2. antaa sitten näin luetulle merkkijonolle nimeksi z. määrittelyjä jotka ovat let-lausekkeita. Niihin ei kuitenkaan kirjoiteta omaa inosaa, vaan määrittelyt näkyvät tästä lauseeesta alkaen tämän do-lausekkeen loppuun (ellei jokin myöhäisempi hahmo tai määrittely peitä niitä näkyvistä). lausekkeita jotka voivat olla mitä tahansa Haskell-lausekkeita, kunhan ne vain ovat Monadista tyyppiä M ν. Esimerkiksi lauseke if null z then return () else do putstrln z main tutkii, onko merkkijono nimeltä z tyhjä vaiko ei. Jos se on tyhjä, niin ei tehdä mitään; muuten ensin tulostetaan z ja sitten palataan takaisin pääohjelman main alkuun. Kummankin if-haaran tyyppi on IO (). Näin saammekin ensimmäisen itsenäisen Haskell-ohjelmamme, joka lukee merkkijonoja syötteestä ja kaiuttaa ne tulosteenaan kunnes saa tyhjän merkkijonon jolloin se lopettaa: module Main(main) where 102

18 main :: IO () main = do z <- getline if null z then return () else do putstrln z main 7.2 I/O-kirjaston operaatioita Preluden perusfunktioita tekstimuotoiseen tulostukseen oletustulosvirtaan stdout ovat putchar :: Char -> IO () joka tulostaa yhden merkin putstr :: String -> IO () joka tulostaa merkkijonon putstrln :: String -> IO () joka tulostaa merkkijonon ja rivinvaihdon print :: Show a => a -> IO () joka on putstrln. show ja jota tulkki ghci kutsuu laskemalleen arvolle silloin kun sen tyyppi kuuluu tähän tyyppiluokkaan. syötteen lukemiseen oletussyötevirrasta stdin ovat getchar :: IO Char joka lukee yhden merkin getline :: IO String joka lukee yhden rivin. Jos syötteen tiedetään esittävän jokin tyypina jotakin arvoa x, niin silloin tämä x saadaan seuraavilla funktioilla: readio :: Read a => String -> IO a joka konvertoi annetun merkkijonon tyypin a arvoksi x readln :: Read a => IO a joka lukee syöterivin oletussyötevirrasta stdin ja konvertoi sen. Jos merkkijonoa konvertoitaessa törmätäänkin syntaksivirheeseen, niin siitä seuraa I/O-poikkeus, jonka ohjelmoija voi käsitellä. Oletussyötevirran stdin laiskaan lukemiseen on funktio getcontents :: IO String joka palauttaa sen koko (jäljellä olevan) sisällön laiskana merkkijonona, jota luetaan sitä mukaa kun ohjelma etenee sen merkistä seuraavaan. Se on kauniin deklaratiivinen (joskin hieman hidas) tapa lukea syöte eräajo-ohjelmaan, koska siihen voi soveltaa kaikkia Haskellin tarjoamia listankäsittelyfunktioita. Yksinkertaisten tekstipohjaisten tilattomien vuorovaikutteisten ohjelmien laatimiseen taas on funktio interact :: (String -> String) -> IO () jonka parametri 103

19 saa syötteenään oletussyötevirran stdin koko (jäljellä olevan) sisällön laiskasti luettavana merkkijonona antaa tulosteensa toisena merkkijonona jota se voi rytmittää rivinvaihdoilla. Esimerkiksi: module Main(main) where main :: IO () main = interact (concatmap ((++"\n"). reverse). lines) Mutkikkaammat I/O-operaatiot kuten esimerkiksi tiedostojen käsittely löytyvät vakiokirjastosta System.IO. Esimerkiksi usein halutaan oletustulosvirta stdout sellaiseksi, ettei sitä puskuroidakaan. Siihen tämä kirjasto tarjoaa kutsun hsetbuffering stdout NoBuffering jonka voi sijoittaa sellaisen ohjelman mainin alkuun. Poikkeuksista Poikkeuksia (exception) on hankala sovittaa yhteen puhtaan funktionaalisen ohjelmoinnin kanssa: Se milloin poikkeus käsitellään olettaa, että ohjelmoija tietäisi milloin jotakin tapahtuu laskennan kuluessa mutta puhtaassa funktionaalisessa ohjelmoinnissahan ohjelmoija tietää korkeintaan että se joskus tapahtuu... Haskellin vakiokirjasto System.IO.Error tarjoaakin yksinkertaisen poikkeusmekanismin erilaisten I/O-virheiden käsittelyyn koska Monadissa IO on tällainen järjestys ensin lasketaan tämä, ja sitten vasta tuo... Toteutuksen ghc mukana tulee myös sen oma toinenkin kirjasto Control.Exception jolla poikkeuksia voi nostaa muuallakin kuin Monadissa IO mutta nekin voi käsitellä vain siellä tämän järjestyksen vuoksi. Vakiokirjaston I/O-poikkeusmekanismi koostuu tyypistä IOError eli jokin I/Ovirhe sekä funktioista ioerror :: IOError -> IO a joka nostaa parametrina ilmoitetun I/O-poikkeuksen catch :: IO a -> (IOError -> IO a) -> IO a jonka ensimmäinen parametri on I/O-tyyppinen lauseke (kuten esimerkiksi jokin do-lauseke) jonka laskenta voi aiheuttaa I/O-poikkeuksia. Jos niitä ei aiheudu, niin catchin arvoksi tulee tämän laskennan antama arvo. jälkimmäinen parametri on funktio, jota kutsutaan, jos näin käy. Se saa parametrinaan sen aiheutuneen poikkeuksen. 104

20 Se voi käsitellä kyseisen poikkeustilanteen palauttamalla jonkin arvon, josta tulee tämän catchin arvo. Jos se ei osaakaan käsitellä tilannetta, niin sen pitääkin nostaa sama poikkeus uudelleen, jolloin tilanteen käsittelyvastuu siirtyykin seuraavalle ulommalle catchille. Jos mikään catch ei osaakaan sitä käsitellä, niin silloin koko mainin laskenta keskeytyy suoritusaikaiseen virheeseen. try :: IO a -> IO (Either IOError a) joka yrittää suorittaa parametrinaan saamansa laskennan. Jos sen arvo on Right x niin tämä laskenta onnistui virheettä ja x on sen lopputulos Left e niin silloin tämä laskenta johtikin poikkeukseen e. Otetaan sitten esimerkiksi I/O-ohjelmoinnista nelilaskin, jossa pidetään muistissa yhtä liukulukua käyttäjä voi antaa komentonaan lisää/vähennä/kerro/jaa se luvulla... tämän komentorivin mahdolliset virheet käsitellään tyhjä komentorivi lopettaa ohjelman suorituksen. 7.3 Maybe monadina Aiemmin näimme, miten Maybe on Monadi: instance Monad Maybe where (Just x) >>= k = k x Nothing >>= k = Nothing return = Just fail s = Nothing Tarkastellaan sitä tässä valossa, että lausekkeen p >>= k voi lukea myös suorita ensin laskenta p ja sovella sitten sen tulokseen x funktiota k. Silloin näemme uuden tulkinnan Maybelle: Jos laskenta p sai jonkin tuloksen x niin sovella siihen funktiota k, mutta jos se ei saanutkaan mitään tulosta, niin koko loppulaskentakaan ei saa mitään tulosta koska siitä alkaen jokaisen (>>=)-operaattorin vasen parametri on aina Nothing. Silloin siis jokainen Maybe-tyyppisen do-lauseen hahmo <- kutsuttava ohitetaan kokonaan, jos jokin sitä edeltävistä tällaisista lauseista on jo tuottanut arvon Nothing siinä kutsuttava laskenta tuottaakin sellaisen arvon, joka ei olekaan muotoa olekaan muotoa Just hahmo. Silloin siis tästä alkaen kaikki lauseet ohitetaan. Siten tässä valossa Maybe antaakin tyypin sellaiselle laskennalle joka päättyy epäonnistumiseen jos yksikin siinä kutsuttava laskenta epäonnistuu. 105

21 7.4 Lista monadina Olemme nähneet jo aiemmin, miten listat ovat Monadi: instance Monad [] where m >>= k = concat (map k m) return x = [x] fail s = [] Tarkastellaan sitäkin tässä valossa, että lausekkeen p >>= k voi lukea myös suorita ensin laskenta p ja sovella sitten sen tulokseen x funktiota k. Nyt sen koko laskenta etenee seuraavasti: 1. Laskenta p tuottaa tuloksenaan listan m eli [x 1, x 2, x 3,...]. 2. Sen jokaiseen alkioon x i sovelletaan (map) funktiota k. 3. Jokainen sovellus k x i tuottaa tuloksenaan jonkin listan [y 1 i, y 2 i, y 3 i,...]. 4. Yhdistetään (concat) nämä listat yhdeksi listaksi k x 1 ++ k x 2 ++ k x Sitten ympäröivässä listamonadilausekkeessa >>=k sovelletaan seuraavaa funktiota k jokaiseen tämän listan alkioon y j i, jne. Vaihdetaan näkökulmaa kokonaisista listoista niiden yksittäisiin alkioihin: Ajatellaan, että alkio x i edustaisi jotakin tilaa, jossa koko laskenta voisi olla tällä hetkellä. Silloin k x i tuottaa sille monta eri mahdollista seuraavaa tilaa y j i. Tässtä näkökulmasta k on siis epädeterministinen seuraava laskenta-askel. Tässä valossa listamonadi ja sen do-syntaksi kuvaavat epädeterministisen laskennan kaikkien eri vaihtoehtojen seuraamiseen. Deklaratiivisesti yksi tällainen epädeterministinen askel hahmo <- kutsuttava voidaan lukea valitse mikä tahansa hahmo on sopiva vaihtoehto kutsuttava n laskennan antamista mahdollisuuksista. Tässä luennassa <- on. 106

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

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006 Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet TIES341 Funktio-ohjelmointi 2 Kevät 2006 Alkuperäislähteitä Philip Wadler & Stephen Blott: How to make ad-hoc polymorphism less ad-hoc,

Lisätiedot

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tällä luennolla Algebralliset tietotyypit Hahmonsovitus (pattern matching) Primitiivirekursio Esimerkkinä binäärinen hakupuu Muistattehan...

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 14: Monadit Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Tyyppien tyypit eli luonteet engl. kind tyyppinimet, kuten

Lisätiedot

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

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla 2.5. YDIN-HASKELL 19 tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla kirjaimilla. Jos Γ ja ovat tyyppilausekkeita, niin Γ on tyyppilauseke. Nuoli kirjoitetaan koneella

Lisätiedot

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

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tyyppejä ja vähän muutakin TIEA341 Funktio ohjelmointi 1 Syksy 2005 Viime luennolla... Haskellin alkeita pääasiassa Hello World!... ja muita tutunoloisia ohjelmia Haskellilla Haskellin voima on kuitenkin

Lisätiedot

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

Laajennetaan vielä Ydin-Haskellia ymmärtämään vakiomäärittelyt. Määrittely on muotoa 2.6. TIETOKONE LASKIMENA 23 Edellä esitetty Ydin-Haskell on hyvin lähellä sitä kieltä, jota GHCi (Glasgow Haskell Compiler, Interactive) sekä muut Haskell-järjestelmät suostuvat ymmärtämään. Esimerkiksi:

Lisätiedot

6 Algebralliset tietotyypit

6 Algebralliset tietotyypit Nyt voitaisiin kirjoittaa instance Functor Set where type Inv Set e = (Ord e) fmap = map jossa metodin tyyppi onkin nyt fmap :: (Ord a,ord b) => (a -> b) -> Set a -> Set b joka onkin nyt samaa tyyppiä

Lisätiedot

Abstraktit tietotyypit. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Abstraktit tietotyypit. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Abstraktit tietotyypit TIEA341 Funktio ohjelmointi 1 Syksy 2005 Data abstraktio Abstraktio on ohjelmoinnin tärkein väline Data abstraktio abstrahoi dataa Abstrakti tietotyyppi Koostuu kolmesta asiasta:

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 5 Ympärysmitta. Puut. Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 CASE: YMPÄRYSMITTA Lasketaan kuvioiden ympärysmittoja

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 6 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 4 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 17. tammikuuta 2008 Modulin viimeistelyä module Shape ( Shape ( Rectangle, E l l i p

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 9 Kombinaattoreista Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Currying Haskell-funktio ottaa aina vain yhden

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2011 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2011 1 / 39 Kertausta: tiedoston avaaminen Kun ohjelma haluaa lukea tai kirjoittaa tekstitiedostoon, on ohjelmalle

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 28.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 28.2.2011 1 / 46 Ohjelmointiprojektin vaiheet 1. Määrittely 2. Ohjelman suunnittelu (ohjelman rakenne ja ohjelman

Lisätiedot

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

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 25.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 25.2.2009 1 / 34 Syötteessä useita lukuja samalla rivillä Seuraavassa esimerkissä käyttäjä antaa useita lukuja samalla

Lisätiedot

Luku 3. Listankäsittelyä. 3.1 Listat

Luku 3. Listankäsittelyä. 3.1 Listat Luku 3 Listankäsittelyä Funktio-ohjelmoinnin tärkein yksittäinen tietorakenne on lista. Listankäsittely on paitsi käytännöllisesti oleellinen aihe, se myös valaisee funktio-ohjelmoinnin ideaa. 3.1 Listat

Lisätiedot

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

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Luku 4. Tietorakenteet funktio-ohjelmoinnissa. 4.1 Äärelliset kuvaukset

Luku 4. Tietorakenteet funktio-ohjelmoinnissa. 4.1 Äärelliset kuvaukset Luku 4 Tietorakenteet funktio-ohjelmoinnissa Koska funktio-ohjelmoinnissa ei käytetä tuhoavaa päivitystä (sijoituslausetta ja sen johdannaisia), eivät läheskään kaikki valtavirtaohjelmoinnista tutut tietorakenteet

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 1.3.2010 1 / 36 Monikko Monikko (engl. tuple) muistuttaa listaa, mutta monikon sisältöä ei voi muuttaa sen jälkeen,

Lisätiedot

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

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin Raimo Nikkilä Aalto-yliopiston sähkötekniikan korkeakoulu - Automaation tietotekniikan tutkimusryhmä 17. tammikuuta 2013

Lisätiedot

Monadeja siellä, monadeja täällä... monadeja kaikkialla? TIES341 Funktio ohjelmointi 2 Kevät 2006

Monadeja siellä, monadeja täällä... monadeja kaikkialla? TIES341 Funktio ohjelmointi 2 Kevät 2006 Monadeja siellä, monadeja täällä... monadeja kaikkialla? TIES341 Funktio ohjelmointi 2 Kevät 2006 Materiaalia Paras verkkomatsku: http://www.nomaware.com/monads/html/ Komentoanalogiasta vielä Monadityypin

Lisätiedot

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4 Sisällys 12. Näppäimistöltä lukeminen Arvojen lukeminen näppäimistöltä yleisesti. Arvojen lukeminen näppäimistöltä Java-kielessä.. Luetun arvon tarkistaminen. Tietovirrat ja ohjausmerkit. Scanner-luokka.

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset 815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 3 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 14. tammikuuta 2008 Viittausten läpinäkyvyyden 1 periaatteet 1. Lausekkeen arvo ei riipu

Lisätiedot

8. Näppäimistöltä lukeminen 8.1

8. Näppäimistöltä lukeminen 8.1 8. Näppäimistöltä lukeminen 8.1 Sisällys Arvojen lukeminen näppäimistöltä Java-kielessä. In-luokka. In-luokka, käännös ja tulkinta Scanner-luokka. 8.2 Yleistä Näppäimistöltä annettujen arvojen (syötteiden)

Lisätiedot

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

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta C++ - perusteet Java-osaajille luento 5/7: operaattoreiden ylikuormitus, oliotaulukko, parametrien oletusarvot, komentoriviparametrit, constant, inline, Operaattoreiden ylikuormitus Operaattoreiden kuormitus

Lisätiedot

Haskell ohjelmointikielen tyyppijärjestelmä

Haskell ohjelmointikielen tyyppijärjestelmä Haskell ohjelmointikielen tyyppijärjestelmä Sakari Jokinen Helsinki 19. huhtikuuta 2004 Ohjelmointikielten perusteet - seminaarityö HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos 1 Johdanto 1 Tyyppien

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 16.3.2009 1 / 40 Kertausta: tiedostosta lukeminen Aluksi käsiteltävä tiedosto pitää avata: tiedostomuuttuja = open("teksti.txt","r")

Lisätiedot

5.5 Jäsenninkombinaattoreista

5.5 Jäsenninkombinaattoreista 5.5. JÄSENNINKOMBINAATTOREISTA 67 type Env α = FiniteMap String α data EnvT m α = MkE (Env Integer m (Env Integer, α)) instance Transformer EnvT where promote mp = MkE $ λenv mp λr return $(env, r) instance

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 17.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 17.2.2010 1 / 41 Sanakirja Monissa sovelluksissa on tallennettava rakenteeseen avain arvo-pareja. Myöhemmin rakenteesta

Lisätiedot

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Kirjoita jokaiseen palauttamaasi konseptiin kurssin nimi, kokeen päivämäärä, oma nimi ja opiskelijanumero. Vastaa kaikkiin tehtäviin omille konsepteilleen.

Lisätiedot

ELM GROUP 04. Teemu Laakso Henrik Talarmo

ELM GROUP 04. Teemu Laakso Henrik Talarmo ELM GROUP 04 Teemu Laakso Henrik Talarmo 23. marraskuuta 2017 Sisältö 1 Johdanto 1 2 Ominaisuuksia 2 2.1 Muuttujat ja tietorakenteet...................... 2 2.2 Funktiot................................

Lisätiedot

main :: IO () main = interact (concatmap ((++"\n"). reverse). lines)

main :: IO () main = interact (concatmap ((++\n). reverse). lines) saa syötteenään oletussyötevirran stdin koko (jäljellä olevan) sisällön laiskasti luettavana merkkijonona antaa tulosteensa toisena merkkijonona jota se voi rytmittää rivinvaihdoilla. Esimerkiksi: module

Lisätiedot

12. Näppäimistöltä lukeminen 12.1

12. Näppäimistöltä lukeminen 12.1 12. Näppäimistöltä lukeminen 12.1 Sisällys Arvojen lukeminen näppäimistöltä yleisesti. Arvojen lukeminen näppäimistöltä Java-kielessä. In-luokka. Luetun arvon tarkistaminen. Tietovirrat ja ohjausmerkit.

Lisätiedot

8. Näppäimistöltä lukeminen 8.1

8. Näppäimistöltä lukeminen 8.1 8. Näppäimistöltä lukeminen 8.1 Sisällys Arvojen lukeminen näppäimistöltä Java-kielessä. In-luokka. In-luokka, käännös ja tulkinta Scanner-luokka. 8.2 Yleistä Näppäimistöltä annettujen arvojen (syötteiden)

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Geneerinen ohjelmointi. Lueteltu tyyppi enum. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien silmukoimiseen:

Lisätiedot

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista Sisällys 1. Omat operaatiot Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

1. Omat operaatiot 1.1

1. Omat operaatiot 1.1 1. Omat operaatiot 1.1 Sisällys Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 3.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 3.3.2010 1 / 44 Kertausta: tiedoston avaaminen Kun ohjelma haluaa lukea tai kirjoittaa tekstitiedostoon, on ohjelmalle

Lisätiedot

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti: 1 (7) Tiedon lukeminen näppäimistöltä Scanner-luokan avulla Miten ohjelma saa käyttöönsä käyttäjän kirjoittamaa tekstiä? Järjestelmässä on olemassa ns. syöttöpuskuri näppäimistöä varten. Syöttöpuskuri

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 20.1.2010 T-106.1208 Ohjelmoinnin perusteet Y 20.1.2010 1 / 40 Arvon pyytäminen käyttäjältä Käyttäjän antaman arvon voi lukea raw_input-käskyllä. Käskyn sulkujen

Lisätiedot

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla Tietojen syöttäminen ohjelmalle Tähän mennessä on käsitelty Javan tulostuslauseet System.out.print ja System.out.println sekä ohjelman perusrakenneosat (muuttujat, vakiot, lauseet). Jotta päästään tekemään

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 4.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 4.3.2009 1 / 35 Tiedostot Tiedostojen käsittelyä tarvitaan esimerkiksi seuraavissa tilanteissa: Ohjelman käsittelemiä

Lisätiedot

Lisää pysähtymisaiheisia ongelmia

Lisää pysähtymisaiheisia ongelmia Lisää pysähtymisaiheisia ongelmia Lause: Pysähtymättömyysongelma H missä H = { w111x w validi koodi, M w ei pysähdy syötteellä x } ei ole rekursiivisesti lueteltava. Todistus: Pysähtymisongelman komplementti

Lisätiedot

Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005

Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005 Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005 Esimerkki: Laskin Liukulukulaskentaa Yhteen, vähennys, kerto ja jakolaskut Syötteenä laskutehtävä, tulosteena tulos tai virheilmoitus

Lisätiedot

Tämän vuoksi kannattaa ottaa käytännöksi aina kirjoittaa uuden funktion tyyppi näkyviin, ennen kuin alkaa sen määritemää kirjoittamaan.

Tämän vuoksi kannattaa ottaa käytännöksi aina kirjoittaa uuden funktion tyyppi näkyviin, ennen kuin alkaa sen määritemää kirjoittamaan. 3.1. LISTAT 35 destaan pisteittäisesti: init :: [α] [α] init (x : []) = [] init (x : xs) = x : init xs Varuskirjastoon kuuluu myös funktiot take ja drop, jotka ottavat tai tiputtavat pois, funktiosta riippuen,

Lisätiedot

Ohjelmoinnin perusteet, syksy 2006

Ohjelmoinnin perusteet, syksy 2006 Ohjelmoinnin perusteet, syksy 2006 Esimerkkivastaukset 1. harjoituksiin. Alkuperäiset esimerkkivastaukset laati Jari Suominen. Vastauksia muokkasi Jukka Stenlund. 1. Esitä seuraavan algoritmin tila jokaisen

Lisätiedot

Harjoitus 5 (viikko 48)

Harjoitus 5 (viikko 48) Moni tämän harjoituksen tehtävistä liittyy joko suoraan tai epäsuorasti kurssin toiseen harjoitustyöhön. Harjoitustyö edistyy sitä paremmin, mitä enemmän tehtäviä ratkaiset. Mikäli tehtävissä on jotain

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 11 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Listakomprehensio Uusi tapa luoda (ja muokata) listoja: [ lauseke

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä Rekursiolause Laskennan teorian opintopiiri Sebastian Björkqvist 23. helmikuuta 2014 Tiivistelmä Työssä käydään läpi itsereplikoituvien ohjelmien toimintaa sekä esitetään ja todistetaan rekursiolause,

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, literaalivakio, nimetty vakio Tiedon merkkipohjainen tulostaminen 1 Tunnus Java tunnus Java-kirjain Java-numero

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Lueteltu tyyppi enum. Override-annotaatio. Geneerinen ohjelmointi. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 16.2.2010 1 / 41 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

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

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A. Tehtävä. Tämä tehtävä on aineistotehtävä, jossa esitetään ensin tehtävän teoria. Sen jälkeen esitetään neljä kysymystä, joissa tätä teoriaa pitää soveltaa. Mitään aikaisempaa tehtävän aihepiirin tuntemusta

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PERUSTIETORAKENTEET LISTA, PINO, JONO, PAKKA ABSTRAKTI TIETOTYYPPI Tietotyyppi on abstrakti, kun se on määritelty (esim. matemaattisesti) ottamatta kantaa varsinaiseen

Lisätiedot

Luku 5. Monadit. 5.1 Siirrännän ongelma

Luku 5. Monadit. 5.1 Siirrännän ongelma Luku 5 Monadit There are lots of books about functional programming in Haskell. They tend to concentrate on the beautiful core of functional programming: higher order functions, algebraic data types, polymorphic

Lisätiedot

5.1 Tyyppiparametrit. Nyt lisäämme parametrit myös data-määrittelyihin: data Nimi tp 1 tp 2 tp 3... tp k =...

5.1 Tyyppiparametrit. Nyt lisäämme parametrit myös data-määrittelyihin: data Nimi tp 1 tp 2 tp 3... tp k =... 5.1 Tyyppiparametrit Nyt lisäämme parametrit myös data-määrittelyihin: data Nimi tp 1 tp 2 tp 3... tp k =... Lisäämme ne myös type- ja newtype-määrittelyihin. Nämäkin parametrit tp i kirjoitetaan pienellä

Lisätiedot

5.3 Laskimen muunnelmia 5.3. LASKIMEN MUUNNELMIA 57

5.3 Laskimen muunnelmia 5.3. LASKIMEN MUUNNELMIA 57 5.3. LASKIMEN MUUNNELMIA 57 Samaan sarjaan kuuluu seuraavakin funktio, jonka määritelmä esittelee muutenkin hyödyllisen tavan kirjoittaa ohjelmia: getline :: IO String getline = getchar λc case c of \n

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CS-A1111 13.9.2017 CS-A1111 Ohjelmoinnin peruskurssi Y1 13.9.2017 1 / 19 Oppimistavoitteet: tämän luennon jälkeen osaat kirjoittaa Python-ohjelman, joka pyytää käyttäjältä lukuja,

Lisätiedot

koska sellainen vaaditaan jotta oma tyyppimme Tree k t pääsee jäseneksi Luokkaan Eq.

koska sellainen vaaditaan jotta oma tyyppimme Tree k t pääsee jäseneksi Luokkaan Eq. Määritellään esimerkkinä hakupuillemme sellainen samuus x == y joka pätee täsmälleen silloin kun puissa x ja y on samat(avain,tietoalkio)-parit riippumatta siitä minkä muotoisia puut x ja y ovat. Olemme

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA34 Funktio-ohjelmointi, kevät 2008 Luento 3 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 2. tammikuuta 2008 Ydin-Haskell: Syntaksi Lausekkeita (e) ovat: nimettömät funktiot: \x

Lisätiedot

Algoritmit 1. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 3 Ti Timo Männikkö Algoritmit 1 Luento 3 Ti 17.1.2017 Timo Männikkö Luento 3 Algoritmin analysointi Rekursio Lomituslajittelu Aikavaativuus Tietorakenteet Pino Algoritmit 1 Kevät 2017 Luento 3 Ti 17.1.2017 2/27 Algoritmien

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 4: Symbolit, derivojaesimerkki, kierroksen 1 ratkaisut (mm. SICP 2.32.3.2) Riku Saikkonen 1. 11. 2011 Sisältö 1 Symbolit ja sulkulausekkeet 2 Lisää Schemestä:

Lisätiedot

Tutoriaaliläsnäoloista

Tutoriaaliläsnäoloista Tutoriaaliläsnäoloista Tutoriaaliläsnäolokierroksella voi nyt täyttää anomuksen läsnäolon merkitsemisestä Esim. tagi ei toiminut, korvavaltimon leikkaus, yms. Hyväksyn näitä omaa harkintaa käyttäen Tarkoitus

Lisätiedot

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b Pythonin Kertaus Cse-a1130 Tietotekniikka Sovelluksissa Versio 0.01b Listat 1/2 esimerkkejä listan peruskäytöstä. > lista=['kala','kukko','kissa','koira'] ['kala','kukko','kissa','koira'] >lista.append('kana')

Lisätiedot

Hakemistojen sisällöt säilötään linkitetyille listalle.

Hakemistojen sisällöt säilötään linkitetyille listalle. Harjoitustyö 1 Harjoitustyö Tehtävä: ohjelmoi Java-kielellä komentoikkunaa (komentotulkkia, komentoriviä) simuloiva olioperustainen ohjelma. Hakemistojen sisällöt säilötään linkitetyille listalle. Työ

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 21.1.2009 T-106.1208 Ohjelmoinnin perusteet Y 21.1.2009 1 / 32 Tyypeistä Monissa muissa ohjelmointikielissä (esim. Java ja C) muuttujat on määriteltävä ennen

Lisätiedot

Harjoitus 2 (viikko 45)

Harjoitus 2 (viikko 45) Mikäli tehtävissä on jotain epäselvää, laita sähköpostia vastuuopettajalle (jorma.laurikkala@uta.fi). Muista lisätä static-määre operaatioidesi otsikoihin, jotta ohjelmasi kääntyvät. Muista noudattaa hyvän

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 2: SICP kohdat 22.2.3 Riku Saikkonen 2. 11. 2010 Sisältö 1 Linkitetyt listat 2 Listaoperaatioita 3 Listarakenteet 4 Gambit-C:n Scheme-debuggeri Linkitetyt

Lisätiedot

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 19. tammikuuta 2012

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 19. tammikuuta 2012 TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 19. tammikuuta 2012 Sisällys Sisällys Muistathan A B -konstruktion 0 k 1 i 2 s 3 s 4 a 5 0 k 1 o 2 i 3 r 4

Lisätiedot

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

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python 8. marraskuuta 2010 Ohjelmointi Perusteet Peruskäsitteitä Olio-ohjelmointi Pythonin alkeet Esittely Esimerkkejä Muuttujat

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

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

Geneeriset tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos Geneeriset tyypit TIES542 Ohjelmointikielten periaatteet, kevät 2007 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 6. maaliskuuta 2007 Kysymys Mitä yhteistä on seuraavilla funktioilla?

Lisätiedot

5. HelloWorld-ohjelma 5.1

5. HelloWorld-ohjelma 5.1 5. HelloWorld-ohjelma 5.1 Sisällys Lähdekoodi. Lähdekoodin (osittainen) analyysi. Lähdekoodi tekstitiedostoon. Lähdekoodin kääntäminen tavukoodiksi. Tavukoodin suorittaminen. Virheiden korjaaminen 5.2

Lisätiedot

TIETORAKENTEET JA ALGORITMIT

TIETORAKENTEET JA ALGORITMIT TIETORAKENTEET JA ALGORITMIT Timo Harju 1999-2004 1 typedef link List; /* Vaihtoehtoisia nimiä */ typedef link Stack; /* nodepointterille */ typedef link Queue typedef struct node Node; /* itse nodelle

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CS-A1111 14.9.2016 CS-A1111 Ohjelmoinnin peruskurssi Y1 14.9.2016 1 / 19 Oppimistavoitteet: tämän luennon jälkeen osaat kirjoittaa Python-ohjelman, joka pyytää käyttäjältä lukuja,

Lisätiedot

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2018-2019 1. Algoritmeista 1.1 Algoritmin käsite Algoritmi keskeinen laskennassa Määrittelee prosessin, joka suorittaa annetun tehtävän Esimerkiksi Nimien järjestäminen aakkosjärjestykseen

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Rekursio Rekursion käyttötapauksia Rekursio määritelmissä Rekursio ongelmanratkaisussa ja ohjelmointitekniikkana Esimerkkejä taulukolla Esimerkkejä linkatulla listalla Hanoin

Lisätiedot

Turingin koneen laajennuksia

Turingin koneen laajennuksia Turingin koneen laajennuksia Turingin koneen määritelmään voidaan tehdä erilaisia muutoksia siten että edelleen voidaan tunnistaa tasan sama luokka kieliä. Moniuraiset Turingin koneet: nauha jakautuu k

Lisätiedot

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki Sisällys JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta Abstrakti luokka ja metodi Rajapintamäärittely (interface) Eero Hyvönen Tietojenkäsittelytieteen laitos Helsingin yliopisto 13.10.2000 E.

Lisätiedot

Tietorakenteet ja algoritmit - syksy 2015 1

Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 2 Tietorakenteet ja algoritmit Johdanto Ari Korhonen Tietorakenteet ja algoritmit - syksy 2015 1. JOHDANTO 1.1 Määritelmiä

Lisätiedot

Lyhyt kertaus osoittimista

Lyhyt kertaus osoittimista , syksy 2007 Kertausta Luento 10 12.10.2007 Syksy 2007 1 Lyhyt kertaus osoittimista char *p; /* char, int, jne ilmoittavat, minkä tyyppisiä */ Keskusmuisti int *q; /* olioita sisältäviin muistilohkoihin

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4) 2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CS-A1111 12.9.2018 CS-A1111 Ohjelmoinnin peruskurssi Y1 12.9.2018 1 / 19 Oppimistavoitteet: tämän luennon jälkeen osaat kirjoittaa Python-ohjelman, joka pyytää käyttäjältä lukuja,

Lisätiedot

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto Sisällys 18. bstraktit tietotyypit Johdanto abstrakteihin tietotyyppeihin. Pino ja jono. Linkitetty lista. Pino linkitetyllä listalla toteutettuna. 18.1 18.2 Johdanto Javan omat tietotyypit ovat jo tuttuja:

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 11.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 11.2.2009 1 / 33 Kertausta: listat Tyhjä uusi lista luodaan kirjoittamalla esimerkiksi lampotilat = [] (jolloin

Lisätiedot

T Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 7 (opetusmoniste, kappaleet )

T Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 7 (opetusmoniste, kappaleet ) T-79144 Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 7 (opetusmoniste, kappaleet 11-22) 26 29102004 1 Ilmaise seuraavat lauseet predikaattilogiikalla: a) Jokin porteista on viallinen

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

Lisätiedot

5/20: Algoritmirakenteita III

5/20: Algoritmirakenteita III Ohjelmointi 1 / syksy 2007 5/20: Algoritmirakenteita III Paavo Nieminen nieminen@jyu.fi Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007 p.1/17 Tämän

Lisätiedot

Funktionimien kuormitus. TIES341 Funktio ohjelmointi 2 Kevät 2006

Funktionimien kuormitus. TIES341 Funktio ohjelmointi 2 Kevät 2006 Funktionimien kuormitus TIES341 Funktio ohjelmointi 2 Kevät 2006 Kertausta ongelma Mikä on (+) operaattorin tyyppi? Num a => a -> a -> a Mikä on (==) operaattorin tyyppi? Eq a => a -> a -> a Mikä on show

Lisätiedot

14. Poikkeukset 14.1

14. Poikkeukset 14.1 14. Poikkeukset 14.1 Sisällys Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla poikkeuksella? Poikkeusten heittäminen.

Lisätiedot

7. Näytölle tulostaminen 7.1

7. Näytölle tulostaminen 7.1 7. Näytölle tulostaminen 7.1 Sisällys System.out.println- ja System.out.print-operaatiot. Tulostus erikoismerkeillä. Edistyneempää tulosteiden muotoilua. 7.2 Tulostusoperaatiot System.out.println-operaatio

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 10 Todistamisesta Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Samuuden todistaminen usein onnistuu ihan laskemalla

Lisätiedot