90 likes | 187 Views
CS 341 Programming Language Design and Implementation. Administrative No homework for the moment :-) A complete functional program A look at the homework…. We now have two styles of FP: recursive higher-order Let's write a small but complete F# program… what's the average on quiz1?. 100
E N D
CS 341 Programming Language Design and Implementation • Administrative • No homework for the moment :-) • A complete functional program • A look at the homework… CS 341 -- 07 Feb 2014
We now have two styles of FP: • recursive • higher-order • Let's write a small but complete F# program… • what's the average on quiz1? 100 60 90 . . average ??? quiz1.txt CS 341 -- 07 Feb 2014
Here's a complete program in F#: #light let averagescore(fn) = let strings = [ for value in System.IO.File.ReadAllLines(fn) -> value ] let scores = List.map System.Int32.Parse strings let sum = List.reduce (fun x y -> x + y) scores let avg = float(sum) / float(List.length scores) avg [<EntryPoint>] let main argv = let result = averagescore("quiz1.txt") printfn "%A" result 0 // return success [ "100"; "60"; "90"; "88"; "100"; . . . ] [ 100; 60; 90; 88; 100; . . . ] => 4872 => 84.01 CS 341 -- 07 Feb 2014
Let's look at some of thehomework questions… • length(L) • median(L) • equal(L1, L2) • vectorMultiply(L1, L2) • RemoveAdjacentDups(L) CS 341 -- 07 Feb 2014
length(L) • Higher-order version anyone? base case: [ ] -> 0 inductive case: _ -> 1 + length(L.Tail) let length(L) = let ones = List.map (fun E -> 1) L let len = List.reduce (fun x y -> x + y) ones len CS 341 -- 07 Feb 2014
let rec getnth(L:'a list, n) = match n with | 1 -> L.Head | _ -> getnth(L.Tail, n-1) • median(L) • A different way to think about cases: cases: [ ] -> 0 // should never happen [E] -> E _ -> if length(L)%2 = 0 then (getnth(L, length(L)/2) + getnth(L, length(L)/2 + 1)) / 2 else getnth(L, length(L)/2 + 1) match length(L)%2 with | 0 -> (getnth(L, length(L)/2) + getnth(L, length(L)/2 + 1)) / 2 | 1 -> getnth(L, length(L)/2 + 1) CS 341 -- 07 Feb 2014
vectorMultiply(L1, L2) • Higher-order solution even better: base case: [ ], [ ] -> [ ] inductive case: _ -> L1.Head * L2.Head :: vectorMultiply(L1.Tail, L2.Tail) let vectorMultiply(L1, L2) = List.map2 (fun E1 E2 -> E1 * E2) L1 L2 CS 341 -- 07 Feb 2014
equal(L1, L2) • Higher-order solution? base cases: [ ], [ ] -> true [ ], _ -> false _ , [ ] -> false inductive case: _ -> L1.Head = L2.Head && equal(L1.Tail, L2.Tail) let equal(L1, L2) = if length(L1) <> length(L2) then false elselet L3 = List.map2 (fun E1 E2 -> E1 = E2) L1 L2 List.reduce (fun E1 E2 -> E1 && E2) L3 CS 341 -- 07 Feb 2014
[ 1;1;1;2;2;5;3;3;4;4;5] • HW3: RemoveAdjacentDups • is this C code correct? [ 1; 2; 5; 3; 4; 5] intRemoveAdjacentDups(int A[], int N) { inti = 0; while (i < N-1) // all but last (last has no dup): { if (A[i] == A[i+1])) // have a dup: { // shift i+2..N elements to the left by one: for (int j=i+1; j<N-1; j++) elements[j] = elements[j+1]; N--; // now one less in array: } i++; } return N; } let rec RemoveAdjDups(L) = match L with | [ ] -> [ ] | [E] -> [E] | _ -> if L.Head = L.Tail.Head then RemoveAdjDups(L.Tail) else L.Head :: RemoveAdjDups(L.Tail) CS 341 -- 07 Feb 2014