• No results found

F6: Högre ordningens funktioner. Mönster för rekursion (1) Mönster för rekursion (1b) Mönster för rekursion (2) Högre Ordningens Funktioner

N/A
N/A
Protected

Academic year: 2022

Share "F6: Högre ordningens funktioner. Mönster för rekursion (1) Mönster för rekursion (1b) Mönster för rekursion (2) Högre Ordningens Funktioner"

Copied!
5
0
0

Loading.... (view fulltext now)

Full text

(1)

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 1


F6: Högre ordningens funktioner

•  Mönster för rekursion

•  Partiellt applicerbara funktioner

•  Anonyma funktioner

•  Op

•  HOF på listor

•  Sortering

•  Listreduktion

•  Funktionskomposition

Mönster för rekursion (1)

•  Rekursivt anrop i lokal deklaration. Speciellt användbart när resultatet av det rekursiva anropet ska

"bearbetas" (ex delas upp) på nåt sätt.

•  Ex: Dela upp en heltalslista i två listor, tal <0 och >=0 fun split [] = ([],[])


| split (x::xs) =


let val (small,large) = split xs
 in if x<0 then (x::small,large)


else (small,x::large)


end;

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 2


Mönster för rekursion (1b)

•  Det rekursiva anropet av huvudfunktionen använder resultatet av bearbetning av första elementet.

• fun f(y,x::xs) = let val (a,b)=help(x,y)
 in f(y+a, (tl xs)@[b])


end;

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 3


Mönster för rekursion (2)

•  Rekursivt anrop i "huvudfunktionskroppen". T ex när bearbetningen av de olika listelementen är (nästan) oberoende av varann.

•  Ex: Givet en lista på studenter (string list), returnera en lista av tripler (pnr, namn, #poäng). Funktionerna get_kurslist, get_pnr och sumpoints finns givna.

fun studlist [] = []


| studlist (name::rest)=


let val kurslista = get_kurslist(name)
 val pnr = get_pnr(name)


in


(pnr, name, sumpoints(kurslista)):: studlist rest
 end;

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 4


Mönster för rekursion (2b)

•  En hjälpfunktion som returnerar ett sammansatt resultat till huvudfunktionen

local 


fun help x= let val a=…


val b=…


val c=…


in (a,b,c) end;

in


fun main (y::ys) = let (a1,b1,c1)= help y


in … a1 … b1 … c1 … main ys … end
 end;

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 5


Högre Ordningens Funktioner

•  Högre ordningens funktioner?

 Funktioner som kan ta funktioner som argument

 Funktioner som kan ge en funktion som resultat

• Partiellt applicerabara funktioner

 ”Funktionen som fullvärdig medlem i språket”

6


(2)

7


Partiellt applicerbara funktioner

•  Ex: skatteberäkning. Min skatt i kronor beror på a) skatteprocenten; b) min lön

fun tax1 tax = (*En funktion som tar en skattesats och returnerar en ny funktion som tar min lön och beräknar skatten. En ”skattetabell” *);

fun tax2 loen = (tax1 UmeaSkatt) loen;

•  Precis så kan man resonera i ML, men kombinera tax1 och tax2 i en funktion

Partiellt applicerbara funktioner

- fun taxdue tax wage = wage*tax div 100;

> val taxdue = fn: int->(int->int)

• taxdue tar en int som parameter och returnerar en funktion av typ int-> int

•  (taxdue 40) är en funktion som tar en parameter wage och beräknar wage*40 div 100

•  taxdue kan appliceras partiellt, på bara en parameter, för att skapa en ny funktion

- val tax20 = taxdue 20;


> val tax20: fn:int->int - tax20 10000;


> val it=2000:int

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 8


”Template” för PA funktioner

•  Generellt mönster för deklaration av högre ordningens (PA) funktioner:

fun fname pat11 pat12 …pat1n = exp1
 | fname pat21 pat22 …pat2n = exp2
 | ………

| fname patk1 patk2 …patkn = expk

•  Samma effekt som en funktion med n parametrar, men kan appliceras partiellt.

•  Exempel: Kolla om lista1 är ett prefix av lista2 fun starts1 [ ] _ = true


| starts1 _ [ ] = false


| starts1 (h1::t1)(h2::t2) = h1=h2 andalso starts1 t1 t2

•  PA funktioner är en delmängd av HOF

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 9
 10


Map

•  Map tar inte bara en funktion som parameter, men är också partiellt applicerbar.

- fun map f [] = []

| map f (x::xs)=(f x)::(map f xs);

 val map=fn: (’a->’b) -> ’a list -> ’b list

sq : int->int

map sq : int list -> int list floor: real->int

map floor: real list -> int list

11


Anonyma funktioner

•  Ett funktionsvärde kan existeras utan att namnges.

Nyckelordet fn används - fn n=>2*n;

> val it=fn:int->int - (fn n=>2*n) 3;

> val it=6:int

•  Generellt utseende fn pattern1 => expression1 | pattern2 => expression2

| patternN => expressionN

12


Anonyma funktioner

•  När ett funktionsvärde av denna typ appliceras på ett argument v matchas v mot mönstren, detta motsvarar evaluering av

case v of pattern1 => expression1 | pattern2 => expression2

| patternN => expressionN

(3)

13


Anonyma funktioner

•  Följande par av deklarationer är inbördes ekvivalenta - val CircleArea= fn r => Math.pi*r*r;

- fun CircleArea r = Math.pi*r*r;

> val CircleArea = fn:real->real

- val f =fn(a,b)=> a*b;

- fun f(a,b)= a*b;

> val f = fn:int*int->int

- val f=fn a=>(fn b=>a*b);

- fun f a b=a*b;

> val f = fn:int->int->int

14


rec

•  Följande definition fungerar ej:

val fact= fn 0=>1 | n=>n*fact(n-1);

•  Vi måste använda nyckelordet rec för en rekursiv definition

val rec fact= fn 0=>1

| n=>n*fact(n-1);

15


mappning

•  Anonyma funktioner kan med fördel ”mappas” på listor mm.

•  Ex:

fun poslist []=[]

| poslist (x::xs)=x>0::poslist xs;

är ekvivalent med

fun poslist lst=map (fn x=> x>0) lst;

eller

val poslist = map (fn x=> x>0);

16


op

•  Infixa funktioner (på par) kan användas i prefix notation genom nyckelordet op.

op +;

val it=fn:int*int->int (op +) (2,3);

val it=5:int;

fun addElems [] = []

| addElems ((x,y)::zs) = (x+y)::addElems zs;

är ekvivalent med

val addElements = map (op +);

17


HOF på listor

• map

är en HOF på listor

•  Filter: Ta fram alla element med en viss egenskap. Givet ett villkor, gå igenom listan och behåll de element som uppfyller villkoret

-fun filter p []=[]

| filter p (x::xs)=if p x then x::filter p xs

else filter p xs;

> val filter = fn:(‘a->bool)->(‘a list->’a list) - filter (fn n=> n mod 2 = 0) [1,2,3,4,5,6,7];

> val it = [2,4,6]:int list

18


HOF på listor

• Filter finns i biblioteket List, liksom ett antal andra nyttiga funktioner som tex:

 exists kollar om det finns ett element i en lista som uppfyller ett predikat

val exists= fn:(‘a->bool)->‘a list->bool

 all kollar om alla element i en lista uppfyller ett predikat

val all = fn:(‘a->bool)->‘a list->bool

 partition delar upp en lista i två (beroende på en predikatfunktion) (jfr unzip)

val partition = 


fn:(‘a->bool)->’a list ->(‘a list * ‘a list)

(4)

19


Sortering

•  Insättningssortering

•  Ta ut första elementet ur listan, sortera resten av listan och sätt in det första elementet på rätt ställe

local

fun insert x [] =[x]

| insert x (y::ys)=if x<y then x::y::ys else y::(insert x ys) in

- fun sort []=[]

| sort (x::xs)=insert x (sort xs) end;

> val sort=fn: ’’a list-> ’’a list

20


Quicksort

•  Välj ett element (tex första), dela upp listan i element som är större än det valda och de som är mindre. Sortera delarna och lägg sedan ihop dem.

fun quick []=[]

| quick [x]=[x]

| quick (x::xs)=

let val small = filter (fn y=>y<=x) xs val large = filter (fn y=>y>x) xs in quick small @ [x] @ quick large

end;

21


foldr / foldl (överkurs)

•  Listreduktion, ex summan av en lista

•  Effekten av foldr (även kallad reduce) kan beskrivas som att vi sätter in ⊗ mellan varje element i listan

•  x1 ⊗ x2 ⊗ … ⊗ xn ⊗ id

•  Med prefix funktionsapplikation kan samma sak beskrivas som

•  ⊗ x1 (⊗ x2 (… (⊗ xn id) …))

•  Elementen i listan summeras från höger till vänster.

(stackrekursiv)

22


foldr

- fun sum xs = foldr (op +) 0 xs;

> val sum = fn: int list -> int;

- sum [1,3,5,7]

> val it = 16:int

- val sum=foldr (op +) 0;

> val sum=fn:int list->int

23


foldl

•  Vi kan också definiera en ”syskon-funktion” till foldr som reducerar från vänster till höger.

foldl f id [x1,x2, ,xn]=

f(xn, …f(x2,f(x1,id))…)

foldl och foldr är utbytbara endast om den funktion som distribueras är kommutativ

 Jämför (1+(2+(3+0))) och (3+(2+(1+0)))

Exempel

•  Ex: logiskt and (foldl / foldr spelar ej roll) - fun andlist lst = 


foldl (fn(a,b) => a andalso b) true lst;

- andlist [true, true, true];


> val it = true:bool

•  Exempel: insättningssortering - fun insert (x,[]) = [x]


| insert (x,(y::ys)) = if x<y then x::y::ys 
 else y::insert (x,ys);

- val sort = foldl insert [];

> val sort = fn : int list -> int list - sort [5, 8, 4, 9, 2, 1, 8, 7];

> val it = [1, 2, 4, 5, 7, 8, 8, 9] : int list

2009-11-06
 Lennart
Edblom,
Inst.
f.


datavetenskap
 24


(5)

25


Funktionskomposition

•  Applicera en funktion på resultatet av en funktionsapplikation, ex sin(cos x)

•  f(g(x)) kan skrivas som (f o g) x infix 3 o;

fun (f o g) x=f(g(x));

•  x har samma typ som domäntypen hos g

•  g x har samma typ som domäntypen hos f

•  Resultatet har samma typ som resultattypen hos f f:’a->’b

g:’c->’a x:’c

o:(’a->’b)*(’c->’a)->’c->’b

26


Funktionskomposition

sqrt o real;

val it=fn:int->real

(sqrt o real) 16;

val it=4.0:real

•  o är fördefinierad i ML

References

Related documents

Eleven kan föra och följa matematiska resonemang om geometriska mönster och mönster i talföljder genom att ställa och besvara frågor som i huvudsak hör till ämnet..

utgör fasta delar av aktivitetsfälten och om de i tid och rum ligger nära andra potentiella utbudspurikter kommer de även att styra aktivitetsfältets övriga utseende. Besök vid

kehus på 1930-talet hade man dock insett att man inte borde göra alltför stora enhetliga områden för just de sämst lottade, bamrika familjerna.

ring får heta kroppsspråk, som samlande term för allt från omedveten hållning till inlärd gestik. Språket, detta rika.. och komplexa system, får alltså metaforiskt beteckna

I det här projektet undersöker Tove Dahlberg och Kristina Hagström-Ståhl tillsammans sångarens handlingsutrymme i den konstnärliga processen, samt relationen mellan

Förutsättningen är också att denna planering riktar sig mot de faktorer som ligger utanför den lokala nivåns kontroll, samt att den ser som främsta uppgift att skapa

[r]

”känner” inte originaldraperingen som designern gör till en början och därför är det viktigt att vara metodisk och noggrann i arbetet med översättningen av draperade plagg