1/28. Forelesning Forelesning / fun f (_,0) = true. 2 f(0,_)=true. 3 f_ =false; 4 val f = fn : int * int -> bool

Like dokumenter
Dagens tema Innføring i ML - del IV

Plan. funksjoner som funksjonsverdi funksjoner som datastruktur. funksjoner som parametre. Høyere-ordens funksjoner. ufullstendige kall.

Plan. funksjoner som funksjonsverdi funksjoner som datastruktur. funksjoner som parametre. Høyere-ordens funksjoner. ufullstendige kall.

Plan. Fortsetter med ML: lister og rekursive typer/funksjoner unntak let-uttrykk moduler og abstrakte datatyper høyere-ordens funksjoner

INF3110 Programmeringsspråk. Dagens tema. Typer (Kapittel 3 frem til ) Innføring i ML (Kapittel & ML-kompendiet.) 1/19

Typer. 1 Type: boolean. 2 Verdimengde: {true, false} 3 Operatorer: NOT, AND, OR... 1/19. Forelesning Forelesning

INF3110 Programmeringsspråk. Dagens tema

Plan. Fortsetter med ML: lister og rekursive typer/funksjoner unntak let-uttrykk moduler og abstrakte datatyper høyere-ordens funksjoner

1-0::[1,2]; 2 - [3,4]; 3 - [1,2] :: [3,4]; 4-1 :: 2 :: 3 :: nil; 5 - "INF" ^ "3110" ^ " er moro"; 6 - rev [1,2,3];

Dagens tema. Innføring i ML - del III (Kapittel & ML-kompendiet.) Unntak Abstrakte datatyper i ML Høyere-ordens funksjoner

Fortsetter med ML: Repetisjon av lister Typer Unntak Moduler og abstrakte datatyper Introduksjon til høyere-ordens funksjoner

Dagens tema. Funksjonelle språk Fortsetter med ML: Typer Unntak Introduksjon til høyere-ordens funksjoner. ML avsluttes etter planen neste uke.

Variable Man kan bruke variable i ML. ML (kap 5 og 6) Nye datatyper INF3110/4110 INF3110/4110 INF3110/4110 INF3110/4110. Variable i ML.

Plan: Funksjonelle språk (Ghezzi&Jazayeri kap.7 frem til 7.4) IN 211 Programmeringsspråk

Plan: Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) Funksjonelle språk. Innføring i ML. typer enkle funksjoner (Fortsetter med ML i to uker til)

Funksjoner: Kun faste funksjoner. Ikke rekursive kall. Funksjonelle språk (kap 4.4) Bakgrunnen for ML

ML (kap 5) INF3110/4110. Bakgrunn Litt historikk. Funksjonelle språk (kap 4.4) Bakgrunnen for ML. Programmeringsspråket ML Hvordan kjøre ML-programmer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

Fiktiv eksamensbesvarelse IN 211 høsten 2001

Løsningsforslag til eksamen i IN 211 høsten 2002

ML (kap 5 og 6) INF3110/4110. Variable i ML. Nye datatyper. Currying. Avanserte listeoperatorer. Typeanalyse

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

INF 1000 høsten 2011 Uke september

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Eivind Gard Lund. 24. Mars 2009 Foilene bygger på 2009 utgaven av Andreas Svendsen

Kapittel 1 En oversikt over C-språket

Høyere-ordens prosedyrer

Haskell. Kjetil Ørbekk. Programvareverkstedet, 19. mars 2009

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

Hjemmeeksamen 1 i INF3110/4110

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

Binære trær: Noen algoritmer og anvendelser

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon

BOKMÅL Side 1 av 5. KONTERINGSEKSAMEN I FAG TDT4102 Prosedyre og objektorientert programmering. Onsdag 6. august 2008 Kl

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

TDT Øvingsforelesning 1. Tuesday, August 28, 12

IN1010 våren januar. Objektorientering i Java

Ark 1 av 18. programmeringsspråkenes. Velkommen til IN 211. verden. IN 211 Programmeringsspråk

Beskrivelse av programmeringsspråket Compila15 INF Kompilatorteknikk Våren 2015

INF1010 våren januar. Objektorientering i Java

Rekursjon og lister. Stephan Oepen & Erik Velldal. 1. februar, Universitetet i Oslo

2 Om statiske variable/konstanter og statiske metoder.

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

Semantisk Analyse del III

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

MAT1030 Plenumsregning 1

LISP PVV-kurs 25. oktober 2012

Del 1 En oversikt over C-programmering

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

Kap 6.4: Typesjekking Foiler ved Birger Møller-Pedersen Forelest av Stein Krogdahl 19. og 23. mars Dagens tema: Typer og typesjekking

Eksamen i SLI230, vår 2003.

MAT1030 Diskret Matematikk

Innlevering 2a i INF2810, vår 2017

Generiske mekanismer i statisk typede programmeringsspråk

Rekursjon som programmeringsteknikk

INF2810: Funksjonell Programmering. Eksamensforberedelser

TDT4165 PROGRAMMING LANGUAGES. Exercise 01 Introduksjon til Oz

2 Om statiske variable/konstanter og statiske metoder.

TDT Prosedyre- og objektorientert programmering

INF Repetisjon: Hvordan bygge treet og analysere? 8. september Typisk situasjon. De problematiske syntaks-diagrammene

Notat 2, ST Sammensatte uttrykk. 27. januar 2006

UNIVERSITETET I OSLO

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Oversikt. INF1000 Uke 2. Repetisjon - Program. Repetisjon - Introduksjon

Programmering i R. 6. mars 2004

Datatyper 2 generatorbasis for T er en endelig mengde T -produsenter som En utspenner hele verdimengden V tilsammen T. utgangspunktet kunne en type ha

Python: Intro til funksjoner. TDT4110 IT Grunnkurs Professor Guttorm Sindre

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

Forelesere. Velkommen til programmeringsspråkenes verden IN211. Praktiske opplysninger. Faglige forutsetninger. Ragnhild Kobro Runde

Anatomien til en kompilator - I

Praktisk informasjon. Repetisjon: While-løkker. I dag. INF1000 (Uke 5) Mer om løkker, arrayer og metoder. Oblig 2 er lagt ut

Verden - Del 2. Steg 0: Oppsummering fra introduksjonsoppgaven. Intro

AlgDat - Øvingsforelesning 1 Introduksjon til Python, lenkede lister og øving 1

UNIVERSITETET I OSLO

Kap.4 Funksjoner. Tre viktig ting ifm. funksjoner: parameter (input) oppskrift (body) for å beregne resultat (output)

Notat 2, ST januar 2005

En implementasjon av binærtre. Dagens tema. Klassestruktur hovedstruktur abstract class BTnode {}

Datatyper og typesjekking

UNIVERSITETET I OSLO

Plenumsregning 1. MAT1030 Diskret Matematikk. Repetisjon: Algoritmer og pseudokode. Velkommen til plenumsregning for MAT1030

Transkript:

Dagens tema Innføring i ML - del IV Mønstergjenkjenning Litt om funksjoner & likhetstyper Anonyme funksjoner Begrenset skop - let Litt av hvert - greit å ta med seg Avsluttende kommentarer - spørsmål? Mønstergjenkjenning Et mønster kan ha følgende form: 1. Et variabelmønster: variabelnavn (: type) 2. Wildcard: matcher alt. Et sammensatt mønster, f.eks.: (mønster-1,..., mønster-n) (Mønstre kan også settes sammen ved hjelp av konstanter for tall, strenger, tegn, etc., konstruktører for datatyper og lister, records, mm.) Deklarasjonen val mønster = uttrykk; er velformet sålenge mønster og uttrykk har samme type. 1/28 Forelesning 5 24.9.200 Forelesning 5 24.9.200 2/28 Mønstergjenkjenning Eksempel på mønster i variabeldeklarasjon: 1 - val ((x,_),(_,y)) = ((100,200),("abcde","fghij")); 2 val x = 100 : int val y = "fghij" : string Mønstergjenkjenning i case-uttrykk: 1 -funfx= 2 case x of (_,0) => true (0,_) => true 4 _ =>false; 5 val f = fn : int * int -> bool - f (1,2); 7 valit=false:bool - fun entotre ls = case ls of [] => false 1 :: 2 :: :: resten => true x :: resten => entotre resten; val entotre = fn : int list -> bool - entotre [9,9,9,9,9,9,1,2,,4,5,]; val it = true : bool Mønstergjenkjenning Mønstergjenkjenning i funksjonsdefinisjoner: I stedet for å bruke case kan vi gjøre slik: 1 - fun f (_,0) = true 2 f(0,_)=true f_ =false; 4 val f = fn : int * int -> bool - fun entotre [] = false entotre (1 :: 2 :: :: resten) = true entotre (x :: resten) = entotre resten; val entotre = fn : int list -> bool (Dette er nøyaktig de samme funksjonene som på forrige side!) Rekkefølgen spiller en rolle: 1 - fun entotre [] = false 2 entotre (x :: resten) = entotre resten entotre (1 :: 2 :: :: resten) = true; 4 Error: match redundant Den samme feilen får vi ved tilsvarende case-uttrykk! Forelesning 5 24.9.200 /28 Forelesning 5 24.9.200 4/28

Litt om funksjoner Hva er en funksjon? Utenfraperspektiv: en mengde av par Innenfraperspektiv: instruksjoner / en algoritme Er f (x) =2 xog g(x) =x+xsamme funksjon? Utenfra: JA! Innenfra: NEI! Dette er skillet mellom et ekstensjonalt og intensjonalt syn på funksjoner. Likhetstyper En likhetstype er type hvor verdiene tillater likhetstester. Likhetstester kan f.eks. ikke utføres på funksjoner! Hva betyr at det at funksjonene f og g er like? Svar: at f (x) =g(x)for alle mulige argumenter x! Hvordan kan vi sjekke det? Umulig. 1 -funfx=2*x; 2 -fungx=x+x; -f=g; 4 stdin:152.1-152. Error: operator and operand don t agree [equality type required] 5 operator domain: Z * Z operand: (int -> int) * (int -> int) I ML brukes a foråangiataer en likhetstype. int * (int * bool) er en likhetstype. int -> (int * bool) er ikke en likhetstype! Forelesning 5 24.9.200 5/28 Forelesning 5 24.9.200 /28 Anonyme funksjoner To måter å skrive det samme på: funfx=x+x: valf=fnx=>x+x; Syntaksen for fn er slik: fn var : type => uttrykk (i stedet for var : type kan man også ha et mønster) Denne evaluerer til en funksjon som tar et argument av typen type og som gir en verdi av typen til uttrykk. var kalles en parameter og uttrykk en kropp. Anonyme funksjoner Eksempler 1 - map (fn x => 1000 + x) [1,2,,4]; 2 val it = [1001,1002,100,1004] : int list 1 - fun toganger f = fn x => f (f x); 2 val toganger = fn : ( a -> a) -> a -> a - toganger (fn str => str ^ " hopp") "hei"; 4 val it = "hei hopp hopp" : string 5 - toganger (toganger (fn str => str ^ " hopp")) "hei"; val it = "hei hopp hopp hopp hopp" : string Funksjonen toganger tar en funksjon f og returnerer en funksjon som anvender f to ganger. Forelesning 5 24.9.200 7/28 Forelesning 5 24.9.200 8/28

Husk at funksjoner er verdier! (som kan brukes som alle andre verdier... ) 1 - fn arg => [arg, arg]; 2 val it = fn : a -> a list 4 - val lagto = (fn arg => [arg, arg]); 5 val lagto = fn : a -> a list 7 - lagto 124; 8 val it = [124,124] : int list; 9 10 - val tofunksjoner = lagto (fn x => 5 * x); 11 val tofunksjoner = [fn,fn] : (int -> int) list 12 1 - (hd tofunksjoner) 100; 14 val it = 500 : int Begrenset skop - let let gjør en deklarasjon tilgjengelig i en begrenset del av koden: let D in E end; hvor D er en liste av deklarasjoner og E et uttrykk (som bruker disse deklarasjonene). Eksempel: 1 - let val x = "hurra " in x^x^x end; 2 val it = "hurra hurra hurra " : string Dette er som lokale variable i en blokk i imperative språk. Forelesning 5 24.9.200 9/28 Forelesning 5 24.9.200 10/28 Begrenset skop - let Let-uttrykk kan spare skrivearbeid, ved at et deluttrykk skrives bare én gang, og kan gi bedre effektivitet, ved at det regnes ut bare én gang. 1 - fun dobbel(x) = x + x; 2 val dobbel = fn : int -> int - fun beregn (x) = 4 let val s = dobbel(x) 5 in (s,~s) 7 end; 8 val beregn = fn : int -> int * int 9 - beregn(); 10 val it = (,~) : int * int Begrenset skop - let Oppgave: Gitt en liste ønsker vi å beregne summen av alle elementene i listen, samt antall elementer i listen. sumlengde([1,2,,4]) (10,4) sumlengde([1,2,,4,5]) (15,5) Vi tar dette eksemplet mot slutten hvis vi får tid. Forelesning 5 24.9.200 11/28 Forelesning 5 24.9.200 12/28

Første forsøk: 1 - fun sum(ls) = 2 case ls of [] => 0 x::r=>x+sum(r); 4 val sum = fn : int list -> int 5 - fun lengde(ls) = 7 case ls of [] => 0 8 x::r=>1+lengde(r); 9 val lengde = fn : a list -> int 10 11 - fun sumlengde(ls) = (sum(ls), lengde(ls)); 12 val sumlengde = fn : int list -> int * int 1 14 - sumlengde([2,,4,5,,7,8,9,22,,44,55,,77,88,99]); 15 val it = (528,1) : int * int Andre forsøk: slå sammen sum og lengde til én funksjon: 1 - fun sumlengde2(ls) = 2 case ls of [] => (0,0) x :: r => (x + #1 (sumlengde2(r)), 4 1 + #2 (sumlengde2(r))); 5 val sumlengde2 = fn : int list -> int * int 7 - sumlengde2([2,,4,5,,7,8,9,22,,44,55,,77,88,99]); 8 val it = (528,1) : int * int Alt er i nå en funksjon, men vi gjør det samme rekursive kallet to ganger! Vi går her gjennom den samme listen to ganger. Forelesning 5 24.9.200 1/28 Forelesning 5 24.9.200 14/28 Tredje forsøk: slå sammen sum og lengde til én funksjon: 1 - fun sumlengde(ls) = 2 case ls of [] => (0,0) x :: r => let val (sum_r,lengde_r) = sumlengde(r) 4 in (x + sum_r, 1 + lengde_r) end; 5 val sumlengde = fn : int list -> int * int 7 - sumlengde([2,,4,5,,7,8,9,22,,44,55,,77,88,99]); 8 val it = (528,1) : int * int Dette gir bedre effektivitet! Legg merke til bruken av mønster i let val (sum r,lengde r) 1 -funpluss(a,b)=a+b; 2 val pluss = fn : int * int -> int - pluss(,4); 4 valit=7:int pluss er her en funksjon som tar et par av heltall (a,b) som argument og som gir et heltall som verdi. (Det er mer presist enn å si at den simpelthen tar to argumenter, a og b.) - fun pluss a b = a + b; val pluss = fn : int -> int -> int -pluss4; valit=7:int pluss er her en funksjon som tar et et heltall a som argument og som gir en funksjon fra heltall til heltall som verdi. Funksjoner på denne formen kalles currierte. Med et funksjonsrom mener vi en mengde funksjoner fra en type til en annen. int -> int kan ses på som et enkelt funksjonsrom. En funksjon av type a -> b -> c tar argumenter av type a og gir funksjoner fra funksjonsrommet over funksjoner fra b til c. Forelesning 5 24.9.200 15/28 Forelesning 5 24.9.200 1/28

1 - fun pluss a b = a + b; 2 val pluss = fn : int -> int -> int -valf=pluss; 4 val f = fn : int -> int 5 -f4; valit=7:int 7 -f8; 8 valit=11:int Kallet pluss kalles ufullstendig/partielt, fordi det har en ufullstendig liste av aktuelle parametre. Dette kallet gir altså en funksjon som funksjonsverdi. En curriert versjon av gjenta eller foldr: 1 - fun foldr f d l = 2 case l of [] => d x :: r => f (x, foldr f d r); 4 val foldr = fn : ( a * b -> b) -> b -> a list -> b Merk at f her er antatt å være en funksjon som tar et par som argument; den er altså ikke en curriert funksjon! foldr, foldl og map (gjenta) er predefinert i ML, filter (plukk) er det ikke. Forelesning 5 24.9.200 17/28 Forelesning 5 24.9.200 18/28 Eksempel på bruk av foldr: 1 -funpluss(a,b)=a+b; 2 val pluss = fn : int * int -> int 4 - val sum = foldr pluss 0; 5 val sum = fn : int list -> int 7 - sum [1,2,,4,5]; 8 valit=15:int - fun gange(x,y) = x*y; val gange = fn : int * int -> int - val prod = foldr gange 1; val prod = fn : int list -> int - prod [1,2,,4,5]; valit=120:int Curry og uncurry 1 -funcurryfxy=f(x,y); 2 valcurry=fn:( a* b-> c)-> a-> b-> c 4 - fun uncurry f(x,y) = f x y; 5 val uncurry = fn : ( a -> b -> c) -> a * b -> c Funksjonen curry lager curriert versjon av en ikke-curriert funksjon, og uncurry det motsatte. Forelesning 5 24.9.200 19/28 Forelesning 5 24.9.200 20/28

Curry og uncurry eksempler: 1 -funcurryfxy=f(x,y); 2 valcurry=fn:( a* b-> c)-> a-> b-> c 4 -funpluss(a,b)=a+b; 5 val pluss = fn : int * int -> int 7 - curry pluss 1 2; 8 valit=:int - fun uncurry f(x,y) = f x y; val uncurry = fn : ( a -> b -> c) -> a * b -> c - fun gange a b = a * b; val gange = fn : int -> int -> int - uncurry gange (,4); val it = 12 : int 1 signature Bag_def = 2 sig type elem Bag 4 val empty: elem Bag 5 val add : elem Bag * elem -> elem Bag val del : elem Bag * elem -> elem Bag 7 val has : elem Bag * elem -> int 8 val union: elem Bag * elem Bag -> elem Bag 9 end; Husk: to fnutt er på elem gir oss tilgang til likhet over denne typen. Forelesning 5 24.9.200 21/28 Forelesning 5 24.9.200 22/28 Implementasjon I: ved liste 1 structure Bag_impl: Bag_def = 2 struct type elem Bag = ( elem * int) list; 4 val empty = []; 5 fun add(b,x) = case b of [] => (x,1)::[] (y,i)::b => if x=y then (y,i+1)::b else (y,i)::add(b,x); 7 fun del(b,x) = case b of [] => [] 8 (y,i)::b => if x=y then if i=1 then b else (y,i-1)::b 9 else (y,i)::del(b,x); 10 11 fun has(b,x) = case b of [] => 0 12 (y,i)::b => if x=y then i else has(b,x); 1 fun union(a,b)= case b of [] => a 14 (y,i)::b => if i=1 then union(add(a,y), b ) 15 else union(add(a,y),(y,i-1)::b ); 1 end; Implementasjon II: ved funksjonsrom 1 structure Bag_impl: Bag_def = 2 struct type elem Bag = elem -> int; 4 fun empty y = 0; 5 fun add(b,x) y = if x=y then (b x)+1 else (b y); fun del(b,x) y = if x=y then (b x)-1 else (b y); 7 fun has(b,x) = b x; 8 fun union(a,b) (x) = (a x) + (b x) ; 9 end; Merk at funksjonsrom ikke har noen likhetsfunksjon i ML; dermed kan vi ikke teste om to bagger er like med denne implementasjonen. En fordel: vi kan definere og regne på uendelige bager. F.eks.: en bag som består av en forekomst av hvert tall. Forelesning 5 24.9.200 2/28 Forelesning 5 24.9.200 24/28

Implementasjon IIb: ved funksjonsrom 1 structure Bag_impl: Bag_def = 2 struct type elem Bag = elem -> int; 4 val empty = fn(y) => 0; 5 fun add(b,x) = fn(y) => if x=y then (b x)+1 else (b y); fun del(b,x) = fn(y) => if x=y then (b x)-1 else (b y); 7 fun has(b,x) = b x; 8 fun union(a,b) = fn(y) => (a y) + (b y) ; 9 end; Her har vi gjort det samme som på forrige foil, men med en litt annen syntaks. Litt av hvert - greit å ta med seg explode : string -> char list: 1 - explode "test"; 2 val it = [#"t",#"e",#"s",#"t"] : char list implode : char list -> string: 1 - implode [#"i",#"n",#"f",#"o"]; 2 val it = "info" : string Forelesning 5 24.9.200 25/28 Forelesning 5 24.9.200 2/28 Litt av hvert - greit å ta med seg infix navn: 1 - infix cons; 2 infix cons - fun (a cons b) = a :: b; 4 val cons = fn : a * a list -> a list 5-12 cons [4,5,]; val it = [12,4,5,] : int list op : - op cons val it = fn : a * a list -> a list - (op cons)(12, [4,5,]); val it = [12,4,5,] : int list - foldr op+ 0 [1,2,,4,5]; valit=15:int Noen fordeler med ML Gjør at vi kan programmere og abstrahere slik vi tenker. Enkel, elegant kode, selv for svært komplekse problemer. (Jfr. dronningproblemet.) Rekursjon blir svært enkelt. Verifikasjon blir enklere. Få side-effekter gjør matematisk analyse greiere. infix gjør at funksjonen som heter navn bare kan anvendes infix. Hvis er infix, så gjør op at man kan benytte funksjonen på par med vanlig prefiks notatsjon.... (statisk typet, polymorfi, typesikkerhet, moduler, høyere-ordens funksjoner, mønstergjenkjenning, støtte for imperativ programmering, klar semantikk) Noen ulemper: ikke objekt-orientert, subtyper, etc. Forelesning 5 24.9.200 27/28 Forelesning 5 24.9.200 28/28