80 likes | 247 Views
CS 341 Programming Language Design and Implementation. Administrative Quiz #3 friday Topics: programming in F#; event-driven programming Today: Discuss HW6 — image processing in F# Practice for Quiz3. Thinking functionally…. [ a; b; c; d; . . . ]. When to use map ?
E N D
CS 341 Programming Language Design and Implementation • Administrative • Quiz #3 friday • Topics: programming in F#; event-driven programming • Today: • Discuss HW6 — image processing in F# • Practice for Quiz3 CS 341 -- 05 Mar 2014
Thinking functionally… [ a; b; c; d; . . . ] • When to use map? • when you have to convert a list to a list • When to use reduce? • when you have to reduce a list to a single value • When to use recursion? • when the above don't apply [ s; t; u; v; . . . ] [ a; b; c; d; . . . ] r [ a; b; c; d; . . . ] .Tail .Head CS 341 -- 05 Mar 2014
Exercise • write a function satisfies that takes a function F and a list L, and counts how many elements eÎ L "satisfy" F — i.e. F(e) returns true recursive? let rec satisfies(F,L) = ??? tail-recursive? higher-order? let zero(x) = if x = 0 then true else false let R = satisfies(zero, [0;1;2;0;-8]) printfn "%A" R // 2 CS 341 -- 05 Mar 2014
Solutions let rec satisfies(F,L) = let rec satisfies(F,L) = let rec satisfies(F,L) =
HW6: Image Processing in F# [ [0; 0; 0; 100; 0; 0; 0; 0; 0; 255; 0; 255; . . . ] ; [0; 0; 0; 0; 255; 175; 0; 0; 0; 0; 0; 0; . . . ] ; [0; 0; 0; 0; 0; 0; 0; 15; 175; 0; 0; 0; . . . ] ; . . . ] CS 341 -- 05 Mar 2014
TransformGrayscale: • Since list to list, use map • but use recursion on row since operating on 3 elements, not 1 let rec private Row2Gray(row) = match row with | [ ] -> [] | _ -> let avg = (row.Head + row.Tail.Head + row.Tail.Tail.Head) / 3 avg::avg::avg::Row2Gray(row.Tail.Tail.Tail) let TransformGrayscale(image:int list list) = List.map Row2Gray image let rec TransformGrayscale(image:int list list) = match image with | [ ] -> [] | _ -> Row2Gray(image.Head) :: TransformGrayscale(image.Tail) CS 341 -- 05 Mar 2014
TransformInvert: • Use map at both levels • also a good example of currying… let private InvertRow depth row = List.map (fun x -> depth – x) row let TransformInvert(depth:int, image:int list list) = List.map (InvertRow depth) image CS 341 -- 05 Mar 2014
TransformFlipHorizontal: let R(row:int list) = row.Head let G(row:int list) = row.Tail.Head let B(row:int list) = row.Tail.Tail.Head let Next(row:int list) = row.Tail.Tail.Tail let rec private FlipRowHorz(row) = match row with | [ ] -> [] | _ -> let pixel = [R(row); G(row); B(row)] FlipRowHorz(Next(row)) @ pixel Slow: 10-15 seconds… (append builds new list every time) let TransformFlipHorizontal(image:int list list) = List.map FlipRowHorz image Fast! 1 second — prepend does not build new list… let rec private FlipRowHorz newrow row = match row with | [ ] -> newrow | _ -> FlipRowHorz (R(row)::G(row)::B(row)::newrow) (Next(row)) let TransformFlipHorizontal(image:int list list) = List.map (FlipRowHorz[]) image