Presentation laddar. Vänta.

Presentation laddar. Vänta.

1 Funktioner Nr 3 Funktionstyper, högre ordningens funktioner och polymorfism.

Liknande presentationer


En presentation över ämnet: "1 Funktioner Nr 3 Funktionstyper, högre ordningens funktioner och polymorfism."— Presentationens avskrift:

1 1 Funktioner Nr 3 Funktionstyper, högre ordningens funktioner och polymorfism

2 2 Explicit typning Systemet kan inte alltid ge typen åt ett uttryck. - fn x => x * x; Error: overloaded variable cannot be resolved : * (MoscowML ger typen int -> int) Vi måste då explict ge typinformation till system så att den kan avgöra vilken operator som avses. Den formella parametern kan ges en typ. fn (name : type) => expression Exempel - (* square an integer *) val sq = fn (x : int) => x * x; > val sq = fn : int -> int

3 3 Varför explicit typning Alla uttryck kan ges en explicit typ (expression : type) Varför bör man? –Krävs ibland för att lösa överlagring –Ge information till en användare –Kontroll av att härled och förväntad typ är lika

4 4 Abstraktion över funktioner Om man abstraherar över en funktion får man en funktion som ger en funktion som resultat. - val taxdue = fn tax => fn sum => sum * tax div 100; > val taxdue = fn : int -> int -> int (taxdue 40) 1000 ==> ((fn tax => fn sum => sum * tax div 100) 40) 1000 ==> (fn sum => sum * 40 div 100) 1000 ==> 1000 * 40 div 100 ==> 40000 div 100 => 400

5 5 Exempel - taxdue 40; > fn : int -> int - (taxdue 40) 1000; > 400 : int - val tax25 = taxdue 25; > val tax25 = fn : int -> int - tax25 1000; > 250 : int

6 6 Fler exempel fn word => word^"s" fn word => word^"ed" fn ending => fn word => word^ending - val endword = fn ending => fn word => word^ending > val endword = fn : string -> string -> string - val plural = endword "s" > val plural = fn : string -> string - val ended = endword "ed" > val ended = fn : string -> string - plural "boat"; > boats : string

7 7 Högre ordningens funktion En funktion som tar en funktion som argument och/eller ger en funktion som resultat

8 8 Funktioner som argument Abstrahera ut funktioner ur funktionskroppen fn func => …(func expression)… val cube = fn (x : int) => x * x * x val doublesq = fn (x : int) => 2 * (sq x) val doublecube = fn (x : int) => 2 * (cube x) - val doublefun = fn func => fn (x : int) => 2 * (func x) > val doublefun = fn : (int -> int) -> int -> int

9 9 Exempel (doublefun sq) 4 ==> ((fn func => fn (x : int) => 2 * (func x)) sq) 4 ==> (fn (x : int) => 2 * (sq x)) 4 ==> 2 * (sq 4) ==> 2 * 16 ==> 32

10 10 Exempel val fourth = fn (x : int) => sq (sq x) val ninth = fn (x : int) => cube (cube x) - val twice = fn f => fn (x : int) => f (f x) > val twice = fn : (int -> int) -> int -> int (twice sq) 4 ==> ((fn f => fn (x : int) => f (f x)) sq) 4 ==> (fn (x : int) => sq (sq x)) 4 ==> sq (sq 4) ==> sq 16 ==> 256 val fourth = twice sq val ninth = twice cube

11 11 Polymorfism När typen hos ett värde (funktion) innehåller typvariabler En typvariabel kan anta vilken typ som helst Polymorfism ger funktioner möjlighet att ta argument av olika typ. Istället för att skapa flera funktioner som gör exakt samma sak men på olika typer, skapar vi en funktion som är polymorf och därför kan ta olika typ på argument.

12 12 Exempel - val doublefun = fn func => fn (n:int)=> 2*func n; > val doublefun = fn : (int -> int) -> int -> int - val doublefun = fn func => fn n => 2 * func n > val doublefun = fn : ('a -> int) -> 'a -> int - val doublefloor = doublefun floor > val doublefloor = fn : real -> int - val doublersize = doublefun size > val doublesize = fn : string -> int - val twice = fn f => fn x => f (f x) > val twice = fn : ('a -> 'a) -> 'a -> 'a - val double_s = twice plural > val double_s = fn : string -> string - double_s "lo"; > "loss" : string

13 13 Polymorfa funktioner, tre fall Den formella parametern använd aldrig. - fun three x = 3; > val three = fn : 'a -> int Den formella parametern flyttas bara omkring. - fun fst (x,y) = x; > val fst = fn : 'a * 'b -> 'a Den formella parametern skickas bara till funktioner som i sig är polymorfa - fun snd_fst (x,y) = snd x > val snd_fst = fn : ('a * 'b) * 'c -> 'b

14 14 Begränsad polymorfism För att kunna testa på likhet behöver inte typen hos argumentet vara mer bestämda än att man vet att de kan jämföras. Alla värden kan testas på likhet utom funktioner (och abstrakta datatyper). Funktioner som använder lika med ( = ) eller skilt ifrån ( <> ) kan ges en delvis polymorf typ. - fun all_eq (x,y,z) = x = y andalso y = z > val all_eq = fn : ''a * ''a * ''a -> bool

15 15 Polymorfism, begränsad polymorfism och överlagring En polymorf funktion undersöker inte innehållet i sitt argument, det är en funktion som kan användas på argument av alla typer. En begränsad polymorf funktion använder sina argument endast för att undersöka likhet och olikhet, den kan användas på argument av alla typer som det går att testa likhet på. En överlagrad funktion är flera funktioner med samma namn, det är typen hos argumentet som avgör vilken av de olika funktionerna som ska användas.

16 16 Funktionskomposition Applicera en funktion på resultatet av en funktionsapplikation sin (cos x) och sqrt (real 25) val compose = fn f => fn g => fn x => f (g x) –x har samma typ som domäntypen hos g –g x har samma typ som domäntypen hos f –resultatet samma typ som resultattypen hos f f : 'a -> 'b g : 'c -> 'a x : 'c compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b

17 17 Exempel - compose sqrt > fn : ('a -> real) -> 'a -> real - (compose sqrt) real > fn : int -> real - compose sqrt real 16 > 4.0 : real compose sqrt real 16 ==> (fn f => fn g => fn x => f (g x)) sqrt real 16 ==> (fn g => fn x => sqrt (g x)) real 16 ==> (fn x => sqrt (real x)) 16 ==> sqrt (real 16) ==> sqrt 16.0 ==> 4.0

18 18 Mer exempel o är samma som compose fast infix (f o g) x = f (g x) - (sqrt o real) 16 > 4.0 : real - val fourth = sq o sq - val ninth = cube o cube - val twice = fn f => f o f > val twice = fn : ('a -> 'a) -> 'a -> 'a

19 19 Räckvidd Alla namn som används måste vara definierade! –Antingen i en värdes deklaration eller som formell parameter Var kan vi använda namn och till vilken introduktion av namnet kopplas användningen avgörs av räckvidden. fn x => fn x => 2 * x –Till vilken abstraktion binds x i 2 * x

20 20 Räckviddsregler Alla programspråk har regler som avgör var namn får användas och hur användningen kopplas till definition En användning av en formell parameter kopplas till den innersta omslutande funktion som binder den formella parametern. Användningen av ett värdesnamn kopplas till den textmässigt senaste definitionen i programmet.

21 21 Exempel Givet följande program: val x = 10; val y = x * 7; val x = 3; val z = x + y; Vilket värde har z?

22 22 The value of it! Värdet av det senast beräknade uttrycket - 34 + 47; > val it = 81 : int - it * it; > val it = 6561 : int - it div 23; > val it = 285 : int

23 23 Funktionsapplikation! Än en gång!! Evaluering av funktionsapplikation funexpr argexpr 1.Evaluera funktionsuttrycket funexpr till en funktion fn name => body. 2.Evaluera argumentet argexpr till ett värde value. 3.Byt ut alla förekomster av den formella parametern name i funktionskroppen body mot argumentets värde value. 4.Evaluera funktionskroppen body.

24 24 Testning!! Att testa sina program är en mycket viktig del av programmeringen. En funktion bör testas med värden som representerar olika tänkbara fall. Kontrollera både de väntade fallen och gränsfallen. –T ex för en funktion som tar strängar som argument kontrollera med tomma strängen ""

25 25 Kommentera dina funktioner med tester (* ------------------------------------------- Namn : twice = fn f => fn x Syfte: Applicerar funktionen f två gånger på x Typ : val twice = fn : ('a -> 'a) -> 'a -> 'a Test : - twice sqrt 625.0; > val it = 5.00000 : real - twice sq 3; > val it = 81 : int ------------------------------------------- *)


Ladda ner ppt "1 Funktioner Nr 3 Funktionstyper, högre ordningens funktioner och polymorfism."

Liknande presentationer


Google-annonser