Högre ordningens listfunktioner nr 6

  • Upload
    shanon

  • View
    29

  • Download
    3

Embed Size (px)

DESCRIPTION

Högre ordningens listfunktioner nr 6. Ackumulerande parametrar Map, filter reduce. Ackumulerande parametrar. En parameter för att skicka tillfällig information mellan olika rekusions steg i en rekursiv funktion Varför: Lagra tillfälliga värden och bära delresultat För att hantera tillstånd - PowerPoint PPT Presentation

Citation preview

  • Hgre ordningens listfunktionernr 6Ackumulerande parametrarMap, filter reduce

  • Ackumulerande parametrarEn parameter fr att skicka tillfllig information mellan olika rekusions steg i en rekursiv funktionVarfr:Lagra tillflliga vrden och bra delresultatFr att hantera tillstndKontrollera rekursion.

  • Lagra tillflliga vrdenStrsta elementet i en lista givet det hittills strstafun max1 bsf [] = bsf : int | max1 bsf (x::xs) = if x > bsf then max1 x xs else max1 bsf xs> val max1 = fn : int -> int list -> intOm det finns minst ett element i listan kan vi hitta det strsta, fr en tom lista blir det ett undantagexception Max> exception Maxfun max (x :: xs) = max1 x xs | max [] = raise Max> val max = fn : int list -> int

  • Testmax [1,4,2,6,5,7,2] ==>max1 1 [4,2,6,5,7,2] ==>max1 4 [2,6,5,7,2] ==>max1 4 [6,5,7,2] ==>max1 6 [5,7,2] ==>max1 6 [7,2] ==>max1 7 [2] ==>max1 7 [] ==>7- max [];uncaught exception Max

  • Lagra delresultatSummera heltalen i en lista, lagra delresultaten i en parameter. Antag att alla vrden i brjan r summerade i en parameter, tag sedan hand om resten av listanfun suma (s:int) (x::xs) = suma (s+x) xs | suma s [] = s> val suma = fn : int -> int list -> intFr att summera en lista lt delsumman vara noll till att brja medfun sumacc xs = suma 0 xsval sumacc = suma 0> val sumacc = int list -> int

  • Jmfrelse mellan sum och sumaccsum [1,2,3,4] ==>1 + sum [2,3,4] ==>1 + (2 + sum [3,4] ==>1 + (2 + (3 + sum [4]) ==>1 + (2 + (3 + (4 + sum []))) ==>1 + (2 + (3 + (4 + 0))) ==>1 + (2 + (3 + 4)) ==>1 + (2 + 7) ==>1 + 9 ==> 10sumacc [1,2,3,4] ==>suma 0 [1,2,3,4] ==>suma (0+1) [2,3,4] ==>suma (1) [2,3,4] ==>suma (1+2) [3,4] ==>suma (3) [3,4] ==>suma (3+3) [,4] ==>suma (6) [4] ==>suma (6+4) [] ==>suma (10) [] ==>10

  • Hantera tillstndEtt tillstnd som frndras vid varje rekursivt anrop hanteras av en parameter. Tillstndet anvnds fr att berkna slutresultatet.fun fname' state [] = MAKERESULT state | fname' state (x::xs) = fname' (TRANSFORMSTATE state x) xsval fname = fname' START_STATE

  • Exempel: Snittpris per enhet i ett lager beroende p antal av varje enhetfun average' (ta, tp) [] = tp / real ta | average' (ta, tp) ((a,p) :: aps) = average' (ta + a,tp + real a * p) aps> val average' = fn : int * real -> (int * real) list -> realval average = average' (0, 0.0)> val average = fn : (int * real) list -> realaverage [(50,23.0),(100,12.0),(67,9.0)];> val it = 13.6082949308756 : real

  • Kontrollera rekursionMotsvarar loop-index, t ex en rknare fr att avgra hur mnga rekursiva anrop som skall gras.Berkna xn fun power x 0 = 1.0 | power x n = x * power x (n-1)> val power = fn : real -> int -> real

  • Generell upprepningfun iter f 0 s = s | iter f n s = iter f (n-1) (f s)> val iter = fn : ('a -> 'a) -> int -> 'a -> 'aBerkna xnfun power x n = iter (fn y => x * y) n 1.0> val power = fn : real -> int -> realpower 7.0 12;> 1.38413E+10 : real

  • twice igen!fun twice f = iter f 2

    twice sq n ==> iter sq 2 n ==> iter sq 1 (sq n) ==> iter sq 0 (sq (sq n)) ==> sq (sq n)

  • InkapslingEtt stor program br delas in i enheter som r s oberoende av varandra som mjligt.Frn en sdan enhet br endast de viktiga bitarna vara synliga utt. De bitar som ska anvndas i andra delar av programmet. De delar som endast anvnds i enheten br inte vara synliga utifrn.Den som anvnder enheten ska inte behva stta sig in i detaljerna i hur enheten fungerar, utan enbart vilken effekt de synliga delarna har.

  • Lokala deklarationer i MLDen slutliga funktionen anropar ofta flera hjlpfunktioner fr att lsa problemet. Dessa kan paketeras ihop och blir synliga endast fr huvudfunktionen men inte utanfr.local declarations1in declarations2endDeklarationerna i declarations1 r endast synliga fram till end i deklarationen.

  • Exempellocal fun suma (s:int) (x::xs) = suma (s+x) xs | suma s [] = sin val sumacc = suma 0endval sumacc = fn : int list -> int

  • Lokala deklarationer i uttryckMan kan ge namn t tillflliga vrden inuti uttryck, det kan vara konstanta vrden men ocks vrden beroende av parametrar eller berkningar som frekommer p flera stllen.let declarationsin expressionendVrdet av lokalt deklarerade namnet r synligt endast fram till end i uttrycket.Vrdet av hela let-uttrycket r vrdet av uttrycket expression.

  • Exempellet val x = 10 in 2*x*xend;> val it = 200:int

  • EkvationslsningLsning av 2:a-gradsekvation (ax2 + bx + c = 0)exception Solvefun solve a b c = let val p = b*b -4.0*a*cin if p >= 0.0 then ((~b+sqrt p)/(2.0*a),(~b-sqrt p)/(2.0*a)) else raise Solveend;> val solve = fn: real-> real->real-> (real * real)solve 1.0 2.0 ~3.0;val it = (1.0,~3.0) : real * real

  • SekvenserEn lista med kvadraten p alla tal mellan 1 och n[sq 1, sq 2, sq 3, , sq n]Frst en funktion som genererar en lista med kvadraten p alla tal mellan m och k.fun sqlist1 m k = if m > k then [] else sq m :: sqlist1 (m+1) kval sqlist1 = fn : int -> int -> int listDen anvnds fr att skapa en funktion frn 1 till nval sqlist = sqlist 1

  • Med lokala deklarationerlocal fun sqlist1 m k = if m > k then [] else sq m :: sqlist1 (m+1) kin val sqlist = sqlist1 1end> val sqlist = fn : int -> int listsqlist 10;> val it = [1,4,9,16,25,36,49,64,81,100] : int list

  • Vnda p en listaAtt vnda p en lista kan ses som att hela tiden flytta frsta elementet till en annan lista. Jmfr med att flytta bckerna i en hg en efter en till en ny hg. Ordningen i den nya hgen kommer att vara den motsatt mot ursprungliga hgen.local fun rev1 rlsf [] = rlsf | rev1 rlsf (x::xs) = rev1 (x::rlsf) xsin val rev = rev1 []endval rev = fn : 'a list -> 'a list

  • Exempelrev [1,2,3] ==>rev1 [] [1,2,3] ==>rev1 [1] [2,3] ==>rev1 [2,1] [3] ==>rev1 [3,2,1] [] ==>[3,2,1]

  • MapOfta vill man utfra samma operation f p alla element i en listaGivet: [x1, x2, , xn] och en funktion fResultat: [f x1, f x2, , f xn]Kvadraten p alla heltal i en listafun sqs [] = [] | sqs (x::xs) = sq x :: sqs xsDenna form kan generaliserasfun map _ [] = [] | map f (x::xs) = f x :: map f xsval map = fn : ('a -> 'b) -> 'a list -> 'b list

  • UtvidgningMap kan ses som en utvidgning av en funktion frn att glla p enstaka vrden till att glla fr listor av sdana vrden.sq : int -> intmap sq : int list -> int listfloor : real -> intmap floor : real list -> int list

  • Exempelsqs [2,4,6] ==>map sq [2,4,6] ==>sq 2 :: map sq [4,6] ==>4 :: map sq [4,6] ==>4 :: sq 4 :: map sq [6] ==>4 :: 16 :: map sq [6] ==>4 :: 16 :: sq 6 :: map sq [] ==>4 :: 16 :: 36 :: map sq [] ==>4 :: 16 :: 36 :: [] ==>[4,16,36]

  • FilterOm man vill plocka bort vissa element frn en lista givet ngot villkor, s kan man g igenom listan och endast behlla de som uppfyller villkoret.Behll endast de jmna talenfun even n = n mod 2 = 0val even = fn : int -> boolfun evens [] = [] | evens (x::xs) = if even x then x :: evens xs else evens xsval evens = fn : int list -> int list

  • GeneraliseraAbstrahera ut villkorsfunktionen (predikatet)fun filter _ [] = [] | filter p (x::xs) = if p x then x :: filter p xs else filter p xsval filter = fn : ('a -> bool) -> 'a list -> 'a listval evens = filter even

  • Exempelevens [1,2,3,4] ==>filter even [1,2,3,4] ==>if even 1 then 1 :: filter even [2,3,4] else filter even [2,3,4] ==>filter even [2,3,4] ==>if even 2 then 2 :: filter even [3,4] else filter even [3,4] ==>2 :: filter even [3,4] ==>2 :: (if even 3 then 3 :: filter even [4] else filter even [4]) ==>2 :: filter even [4] ==>2 :: (if even 4 then 4 :: filter even [] else filter even []) ==>2 :: 4 :: filter even [] ==>2 :: 4 :: [] ==>[2,4]

  • Primtalfun fromto n m = if n > m then [] else n :: fromto (n+1) mval fromto = fn : int -> (int -> int list)fun divides n m = m mod n = 0val divides = fn : int -> (int -> bool)fun sieve [] = [] | sieve (x::xs) = x :: sieve (filter (not o divides x) xs)val sieve = fn : int list -> int listfun primes m = sieve (fromto 2 m)val primes = fn : int -> int list- primes 30;> val it = [2,3,5,7,11,13,17,19,23,29] : int list

  • Ordnade listorDet r vanligt att arbeta med ordnade listor.Fr att kontrollera att en lista r ordnadfun iorder [] = true | iorder [(x:int)] = true | iorder (x1::x2::xs) = x1 bool

  • Exempeliorder [1,3,5,6] ==>1 true andalso iorder [3,5,6] ==>iorder [3,5,6] ==>3 iorder [5,6] ==>5 iorder [6] ==>true

  • Generaliserad ordningDet som gr iorder specifik fr heltal r "
  • Insttning i en ordnad listaOm listan r ordnad med stigande vrden s frblir den ordnad om jag stter in ett element fre det frsta element som r strre n element som jag vill stta in.fun inserti (v:int) [] = [v] | inserti v (x::xs) = if v int list -> int list

  • Generaliserad insttningOm jag erstter jmfrelsen med en funktion p som avgr vilket vrde som r mindre, fr jag en generell insttningsfunktion.fun insert _ v [] = [v] | insert p v (x::xs) = if p v x then v :: x :: xs else x :: insert p v xsval insert = fn : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list

  • Specialiceringval inserti = insert (fn (x:int) => fn y => x int list -> int listval inserts = insert sleval inserts = fn : string -> string list -> string listfun pairle ((x1:int),(y1:int)) (x2,y2) = x1 boolval insertp = insert pairleval insertp = fn : int * int -> (int * int) list -> (int * int) list

  • Insertion sortTa ut frsta elementet ur listan, sortera resten av listan och stt sedan in det frsta elementet (i ordning) i den sorterade listan.fun isort [] = [] | isort (x::xs) = inserti x (isort xs)val isort = fn : int list -> int listGeneraliserar ver insttningsfunktionen.fun sort insert [] = [] | sort insert (x::xs) = insert x (sort insert xs)val sort = fn : ('a -> 'b list -> 'b list) -> 'a list -> 'b list

  • SpecialiseringSpecialicera fr olika typerval isort = sort insertival isort = fn : int list -> int listval ssort = sort insertsval ssort = fn : string list -> string listval psort = sort insertpval psort = fn : (int * int) list -> (int * int) listisort [2,5,1,7,4,9,2,4];val it = [1,2,2,4,4,5,7,9] : int list

  • Reducering/FoldingAtt reducera vrdena i en lista till ett vrde.fun add (x:int) y = x + y fun sum [] = 0 | sum (x::xs) = add x (sum xs)fun concat s1 s2 = s1^s2fun concs [] = "" | concs (x::xs) = concat x (concs xs)Generalisera funktionen och resultatet fr tomma listanfun reduce f b [] = b | reduce f b (x::xs) = f x (reduce f b xs)val reduce = fn : ('a -> 'b -> 'b) -> 'b -> 'a list -> 'b

  • Specialiceraval sum = reduce add 0val sum = fn : int list -> intval concs = reduce concat ""val concs = fn : string list -> stringfun sort insert = reduce insert []val sort = fn : ('a -> ('b list -> 'b list)) -> ('a list -> 'b list)fun cons x xs = x::xsval cons = fn : 'a -> ('a list -> 'a list)fun map f = reduce (cons o f) []val map = fn : ('a -> 'b) -> ('a list -> 'b list)