1 / 15

Mer om Nr 7

Mer om Nr 7. Rekursion, listor, typer och funktioner. Mönstermatchning på listor av tuppler. fun zip [] [] = [] | zip (x::xs) (y::ys) = (x,y) :: zip xs ys | zip _ _ = raise Zip local fun unzip1 (f,s) [] = (f,s) | unzip1 (f,s) ((x,y)::xys) = unzip1 (x::f,y::s) xys

hetal
Download Presentation

Mer om Nr 7

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Mer omNr 7 Rekursion, listor, typer och funktioner

  2. Mönstermatchning på listor av tuppler fun zip [] [] = [] | zip (x::xs) (y::ys) = (x,y) :: zip xs ys | zip _ _ = raise Zip local fun unzip1 (f,s) [] = (f,s) | unzip1 (f,s) ((x,y)::xys) = unzip1 (x::f,y::s) xys in val unzip = unzip1 (nil,nil) end • Behålla ordningen på elementen i listan fun unzip [] = (nil,nil) | unzip ((x,y)::xys) = letval (f,s) = unzip xys in (x::f,y::s) end

  3. Typuttryck • Hur beskrivs en typ dvs hur ser typuttryck ut: Typvariabler: 'a, 'b, … Eqtypvariabler: ''a, ''b, ... Konstanta typer: int, bool, real, string, unit Tuppler: type1 * … * typen Funktioner: type1 -> … -> typen Typfunktioner: type typefunct, type list Flera argument: (type1,…,typen) typefunct

  4. Namngivna typer • Motsvarigheten till namngivna värden är namngivna typer. • Namnet har då exakt samma betydelse som den namngivna typen och de är utbytbara. • Varför namnge typer? • Illustrativa namn. Vi kan använda ett namn som säger vad vi avser att värden av den typen ska betyda. • Kortare uttryck. En långt komplicerat typuttryck kan ges ett kortare namn

  5. Exempel • Istället för en tuppel med olika typer. (string * bool * (int * int)) list • ger vi illustrativa namn åt de olika delarna type regnum = string type enter_or_exit = bool type hour = int type minute = int type time = hour * minute type entry = regnum * enter_or_exit * time type p_house = entry list fun report (ph : p_house) = ... val report = fn : p_house -> …

  6. Polymorfa typuttryck type 'a pair = 'a * 'a fun f ((x,y): 'a pair) = x f (3,4) => 3 f (4.0,3.0) => 4.0 f (true, 5) => TypeClash

  7. Rekursionsformer • Stack rekursiva funktioner • Varje anrop måste vänta in resultat av nästa rekursiva anrop, beräkningarna läggs på en stack. • Ackumulerande rekursion • Ett ackumulerande argument används vid beräkningarna.

  8. Svansrekursion • Evalueringen av en funktionskropp behöver aldrig uppskjutas för att vänta på resultatet från nästa rekursiva anrop. • Resultatet av en funktion är det direkta resultatet av ett rekursivt anrop. exception Last; fun last [ ] = raise Last | last [x] = x | last (x::xs) = last xs; val last = fn : 'a list -> 'a • Ackumulerande rekursion är ofta (ej alltid) svansrekursiv.

  9. Ömsesidig rekursion • Flera funktioner som anropar varandra. Alla funktionerna måste definieras "samtidigt". fun even 0 = true | even n = odd (n-1) and odd 0 = false | odd n = even (n-1); > val even = fn:int -> bool and odd = fn:int -> bool

  10. Flera rekursionsanrop • Linjärrekursion: • Ett anrop ger upphov till ett nytt anrop. • Dubbel rekursion • Ett anrop ger upphov till två nya anrop fun fib 0 = 0 | fib 1 = 1 | fib n = fib (n-1) + fib (n-2); > val fib = fn : int -> int map fib (fromto 0 10); > [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] : int list

  11. Quicksort • Välj ett element (första) dela upp listan element som är större än det valda och de som är mindre. Sortera de delarna och lägg sedan ihop dem. fun quick [] = [] | quick [x:int] = [x] | quick (x::xs) = letval small = filter (fn y => y <= x) xs val large = filter (fn y => y > x) xs in quick small @ [x] @ quick large end val quick = fn : int list -> int list

  12. Nästlad rekursion • En rekursiv funktionsapplikation "inuti" en annan. • Ackermann's funktion fun ack 0 m = m+1 | ack n 0 = ack (n-1) 1 | ack n m = ack (n-1) (ack n (m-1)); val ack = fn : int -> int -> int ack 3 3; > val it = 61 : int ack 3 4; > val it = 125 : int ack 3 5; > val it = 253 : int ack 4 1; > val it = 65533 : int

  13. Curried och uncurried • En curried funktion är partiellt applicerbara. • Dvs en funktion som kan ta "ett argument i taget". Tar ett argument och returnerar en ny funktion som tar nästa argument osv. • Curried - fun add x y :int = x+y; > val add = fn: int -> (int -> int); • Uncurried - fun plus (x,y):int = x+y; > val plus = fn:(int * int) -> int;

  14. Omvandling • Det är alltid möjligt att göra om en ”uncurried” funktion till ”curried” och vice versa. fun curry ff x y = ff (x,y); > val curry = fn: (’a * ’b -> ’c) -> ’a -> ’b -> ’c curry plus; > val it = fn: int -> int -> int curry plus 2 3; > val it = 5:int fun uncurry f (x,y) = f x y > valuncurry=fn:('a->'b->'c)->('a*'b)->'c uncurry add; > val it = fn : (int * int) -> int uncurry add (2,3); > val it = 5 : int

  15. Operatorer uncurried • ML:s operatorer är infixa, ”uncurried”. • op gör en infix operator prefix op / ; val it = fn : real * real -> real op + (2,3); val it = 5 : int curry op+ 2 3; val it = 5 : int

More Related