Exploring Functional Programming in F#: A Complete Overview and Homework Insights
90 likes | 196 Vues
This document provides an in-depth look at Functional Programming (FP) utilizing F#, focusing on recursive and higher-order functions. It includes a complete program for calculating the average score from a quiz, showcasing essential F# syntax and concepts. Various homework questions are discussed, such as computing length, median, and vector multiplication of lists, along with their higher-order solutions. The practical application of functional programming principles is emphasized through code examples and explanations, aiding students in understanding both theoretical and practical aspects of programming languages.
Exploring Functional Programming in F#: A Complete Overview and Homework Insights
E N D
Presentation Transcript
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