Thinking Induc,vely · 2017. 9. 20. · let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -....
Transcript of Thinking Induc,vely · 2017. 9. 20. · let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -....
ThinkingInduc,vely
COS326DavidWalker
PrincetonUniversity
slidescopyright2017DavidWalkerpermissiongrantedtoreusetheseslidesfornon-commercialeduca,onalpurposes
Administra,on• Assignment1dueat11:59tonight!
• Programstyleguide:– hLp://www.cs.princeton.edu/~cos326/style.php
• Readnotes:– func,onalbasics,type-checking,typedprogramming– thinkinginduc,vely(today)– RealWorldOCamlChapter2,3
2
Op,onsAvaluevhastypetop,onifitiseither:
– thevalueNone,or– avalueSomev',andv'hastypet
Op,onscansignalthereisnousefulresulttothecomputa,on
Example:welookupavalueinahashtableusingakey.– Ifthekeyispresent,returnSomevwherevistheassociatedvalue– Ifthekeyisnotpresent,wereturnNone
3
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float =
(x1,y1)
(x2,y2)
a
bc
4
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float = let (x1,y1) = p1 in let (x2,y2) = p2 in
(x1,y1)
(x2,y2)
a
bc
deconstructtuple
5
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float = let (x1,y1) = p1 in let (x2,y2) = p2 in let xd = x2 -. x1 in if xd != 0.0 then (y2 -. y1) /. xd else ???
(x1,y1)
(x2,y2)
a
bc
whatcanwereturn?
avoiddividebyzero
6
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float option = let (x1,y1) = p1 in let (x2,y2) = p2 in let xd = x2 -. x1 in if xd != 0.0 then ??? else ???
(x1,y1)
(x2,y2)
a
bc
weneedanop,ontypeastheresulttype
7
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float option = let (x1,y1) = p1 in let (x2,y2) = p2 in let xd = x2 -. x1 in if xd != 0.0 then Some ((y2 -. y1) /. xd) else None
(x1,y1)
(x2,y2)
a
bc
8
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float option = let (x1,y1) = p1 in let (x2,y2) = p2 in let xd = x2 -. x1 in if xd != 0.0 then (y2 -. y1) /. xd else None
(x1,y1)
(x2,y2)
a
bc
Hastypefloat
Canhavetypefloatop,on
9
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float option = let (x1,y1) = p1 in let (x2,y2) = p2 in let xd = x2 -. x1 in if xd != 0.0 then (y2 -. y1) /. xd else None
(x1,y1)
(x2,y2)
a
bc
Hastypefloat
Canhavetypefloatop,on WRONG:Typemismatch
10
Slopebetweentwopoints
type point = float * float let slope (p1:point) (p2:point) : float option = let (x1,y1) = p1 in let (x2,y2) = p2 in let xd = x2 -. x1 in if xd != 0.0 then (y2 -. y1) /. xd else None
(x1,y1)
(x2,y2)
a
bc
Hastypefloat
doublyWRONG:resultdoesnotmatchdeclaredresult
11
Rememberthetypingruleforif
Returninganop,onalvaluefromanifstatement:
if…thenNone :top,onelseSome(…) :top,on
12
ife1:boolande2:tande3:t(forsometypet)thenife1thene2elsee3:t
Howdoweuseanop,on?
slope : point -> point -> float option
returnsafloatop,on
13
Howdoweuseanop,on?
slope : point -> point -> float option let print_slope (p1:point) (p2:point) : unit =
14
Howdoweuseanop,on?
slope : point -> point -> float option let print_slope (p1:point) (p2:point) : unit = slope p1 p2
returnsafloatop,on;toprintwemustdiscoverifitisNoneorSome
15
Howdoweuseanop,on?
slope : point -> point -> float option let print_slope (p1:point) (p2:point) : unit = match slope p1 p2 with
16
Howdoweuseanop,on?
slope : point -> point -> float option let print_slope (p1:point) (p2:point) : unit = match slope p1 p2 with Some s -> | None ->
Therearetwopossibili,es
Ver,calbarseparatespossibili,es
17
Howdoweuseanop,on?
slope : point -> point -> float option let print_slope (p1:point) (p2:point) : unit = match slope p1 p2 with Some s -> | None ->
Theobjectbetween|and->iscalledapaLern
The"Somes"paLernincludesthevariables
18
Howdoweuseanop,on?
slope : point -> point -> float option let print_slope (p1:point) (p2:point) : unit = match slope p1 p2 with Some s -> print_string ("Slope: " ^ string_of_float s) | None -> print_string "Vertical line.\n"
19
Wri,ngFunc,onsOverTypedData• Stepstowri,ngfunc,onsovertypeddata:
1. Writedownthefunc,onandargumentnames2. Writedownargumentandresulttypes3. Writedownsomeexamples(inacomment)4. Deconstructinputdatastructures5. Buildnewoutputvalues6. Cleanupbyiden,fyingrepeatedpaLerns
• Forop,ontypes:
match … with | None -> … | Some s -> …
whentheinputhastypetop,on,deconstructwith:
whentheoutputhastypetop,on,constructwith:
Some (…) None
20
MOREPATTERNMATCHING
21
RecalltheDistanceFunc,on
type point = float * float let distance (p1:point) (p2:point) : float = let square x = x *. x in let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -. x1) +. square (y2 -. y1))
22
RecalltheDistanceFunc,on
type point = float * float let distance (p1:point) (p2:point) : float = let square x = x *. x in let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -. x1) +. square (y2 -. y1)) ;;
(x2,y2)isanexampleofapaLern–apaLernfortuples.Soletdeclara,onscancontainpaLernsjustlikematchstatementsThedifferenceisthatamatchallowsyoutoconsidermul,pledifferentdatashapes
23
RecalltheDistanceFunc,on
type point = float * float let distance (p1:point) (p2:point) : float = let square x = x *. x in match p1 with | (x1,y1) -> let (x2,y2) = p2 in sqrt (square (x2 -. x1) +. square (y2 -. y1)) ;;
Thereisonly1possibilitywhenmatchingapair
24
RecalltheDistanceFunc,on
type point = float * float let distance (p1:point) (p2:point) : float = let square x = x *. x in match p1 with | (x1,y1) -> match p2 with | (x2,y2) -> sqrt (square (x2 -. x1) +. square (y2 -. y1)) ;;
Wecannestonematchexpressioninsideanother.(Wecannestanyexpressioninsideanyother,iftheexpressionshavetherighttypes)
25
BeLerStyle:ComplexPaLerns
type point = float * float let distance (p1:point) (p2:point) : float = let square x = x *. x in match (p1, p2) with | ((x1,y1), (x2, y2)) -> sqrt (square (x2 -. x1) +. square (y2 -. y1)) ;;
PaLernforapairofpairs:((variable,variable),(variable,variable))AllthevariablenamesinthepaLernmustbedifferent.
webuiltapairofpairs
26
BeLerStyle:ComplexPaLerns
type point = float * float let distance (p1:point) (p2:point) : float = let square x = x *. x in match (p1, p2) with | (p3, p4) -> let (x1, y1) = p3 in let (x2, y2) = p4 in sqrt (square (x2 -. x1) +. square (y2 -. y1)) ;;
ApaLernmustbeconsistentwiththetypeoftheexpressioninbetweenmatch…withWeuse(p3,p4)hereinsteadof((x1,y1),(x2,y2))
webuiltapairofpairs
27
PaLern-matchinginfunc,onparameters
type point = float * float let distance ((x1,y1):point) ((x2,y2):point) : float = let square x = x *. x in sqrt (square (x2 -. x1) +. square (y2 -. y1)) ;;
Func,onparametersarepaLernstoo!
28
What’sthebeststyle?
let distance (p1:point) (p2:point) : float = let square x = x *. x in let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -. x1) +. square (y2 -. y1))
Eitheroftheseisreasonablyclearandcompact.Codewithunnecessarynestedmatches/letsispar,cularlyuglytoread.You'llbejudgedoncodestyleinthisclass.
let distance ((x1,y1):point) ((x2,y2):point) : float = let square x = x *. x in sqrt (square (x2 -. x1) +. square (y2 -. y1))
29
What’sthebeststyle?
ThisishowI'ddoit...thetypesfortuples+thetuplepaLernsarealiLleugly/verbose...butfornowinclass,usetheexplicittypeannota,ons.Wewillloosenthingsuplaterinthesemester.
let distance (x1,y1) (x2,y2) = let square x = x *. x in sqrt (square (x2 -. x1) +. square (y2 -. y1))
30
CombiningpaLerns
type point = float * float (* returns a nearby point in the graph if one exists *) nearby : graph -> point -> point option let printer (g:graph) (p:point) : unit = match nearby g p with | None -> print_string "could not find one\n" | Some (x,y) -> print_float x; print_string ", "; print_float y; print_newline(); ;;
31
OtherPaLerns• ConstantvaluescanbeusedaspaLerns
let small_prime (n:int) : bool = match n with | 2 -> true | 3 -> true | 5 -> true | _ -> false ;; let iffy (b:bool) : int =
match b with | true -> 0 | false -> 1 ;; theunderscorepaLern
matchesanythingitisthe"don'tcare"paLern
32
INDUCTIVETHINKING
33
Induc,veProgrammingandProvingAninduc&vedatatypeTisadatatypedefinedby:
– acollec,onofbasecases• thatdon’trefertoT
– acollec,onofinduc,vecasesthatbuildnewvaluesoftypeTfrompre-exis,ngdataoftypeT• thepre-exis,ngdataisguarateedtobesmallerthanthenewvalues
Programmingprinciple:– solveprogrammingproblemforbasecases– solveprogrammingproblemforinduc,vecasesbycallingfunc,onrecursively(induc,vely)onsmallerdatavalue
Provingprinciple:– proveprogramsa,sfiespropertyPforbasecases– proveinduc,vecasessa,sfypropertyPassuminginduc,vecallsonsmallerdatavaluessa,sfypropertyP
34
LISTS:ANINDUCTIVEDATATYPE
35
ListsareRecursiveData• InOCaml,alistvalueis:
– [] (theemptylist)– v::vs (avaluevfollowedbyashorterlistofvaluesvs)
BaseCaseInduc,veCase
36
ListsareInduc,veData• InOCaml,alistvalueis:
– [] (theemptylist)– v::vs (avaluevfollowedbyashorterlistofvaluesvs)
• Anexample:
– 2::3::5::[]hastypeintlist– isthesameas:2::(3::(5::[]))– "::"iscalled"cons"
• Analterna,vesyntax(“syntac,csugar”forlists):
– [2;3;5]– Butthisisjustashorthandfor2::3::5::[].Ifyouevergetconfusedfallbackonthe2basicconstructors:::and[]
37
TypingLists• Typingrulesforlists:
[]mayhaveanylisttypetlist
ife1:tande2:tlistthen(e1::e2):tlist
(1)
(2)
38
TypingLists• Typingrulesforlists:
• Moreexamples:(1+2)::(3+4)::[]:??(2::[])::(5::6::[])::[] :??[[2];[5;6]] :??
[]mayhaveanylisttypetlist
ife1:tande2:tlistthen(e1::e2):tlist
(1)
(2)
39
TypingLists• Typingrulesforlists:
• Moreexamples:(1+2)::(3+4)::[]:intlist(2::[])::(5::6::[])::[] :intlistlist[[2];[5;6]] :intlistlist(Rememberthatthe3rdexampleisanabbrevia,onforthe2nd)
[]mayhaveanylisttypetlist
ife1:tande2:tlistthen(e1::e2):tlist
(1)
(2)
40
AnotherExample
• Whattypedoesthishave?
[2]::[3]
41
AnotherExample
# [2] :: [3];; Error: This expression has type int but an expression was expected of type int list #
• Whattypedoesthishave?
[2]::[3]
intlist intlist
42
AnotherExample
• Whattypedoesthishave?
[2]::[3]• Givemeasimplefixthatmakestheexpressiontypecheck?
intlist intlist
43
AnotherExample
• Whattypedoesthishave?
[2]::[3]• Givemeasimplefixthatmakestheexpressiontypecheck?
Either:2::[3] :intlistOr:[2]::[[3]] :intlistlist
intlist intlist
44
AnalyzingLists• Justlikeop,ons,therearetwopossibili,eswhen
deconstruc,nglists.Henceweuseamatchwithtwobranches
(* return Some v, if v is the first list element; return None, if the list is empty *) let head (xs : int list) : int option =
45
AnalyzingLists• Justlikeop,ons,therearetwopossibili,eswhen
deconstruc,nglists.Henceweuseamatchwithtwobranches
(* return Some v, if v is the first list element; return None, if the list is empty *) let head (xs : int list) : int option = match xs with | [] -> | hd :: _ ->
wedon'tcareaboutthecontentsofthetailofthelistsoweusetheunderscore
46
AnalyzingLists• Justlikeop,ons,therearetwopossibili,eswhen
deconstruc,nglists.Henceweuseamatchwithtwobranches
• Thisfunc,onisn'trecursive--weonlyextractedasmall,fixedamountofinforma,onfromthelist--thefirstelement
(* return Some v, if v is the first list element; return None, if the list is empty *) let head (xs : int list) : int option = match xs with | [] -> None | hd :: _ -> Some hd
47
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *)
48
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list =
49
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list = match xs with | [] -> | (x,y) :: tl ->
50
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list = match xs with | [] -> [] | (x,y) :: tl ->
51
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list = match xs with | [] -> [] | (x,y) :: tl -> ?? :: ??
theresulttypeisintlist,sowecanspeculatethatweshouldcreatealist
52
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list = match xs with | [] -> [] | (x,y) :: tl -> (x * y) :: ??
thefirstelementistheproduct
53
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list = match xs with | [] -> [] | (x,y) :: tl -> (x * y) :: ??
tocompletethejob,wemustcomputetheproductsfortherestofthelist
54
Amoreinteres,ngexample
(* Given a list of pairs of integers, produce the list of products of the pairs prods [(2,3); (4,7); (5,2)] == [6; 28; 10] *) let rec prods (xs : (int * int) list) : int list = match xs with | [] -> [] | (x,y) :: tl -> (x * y) :: prods tl
55
ThreePartstoConstruc,ngaFunc,on
let rec prods (xs : (int*int) list) : int list = match xs with | [] -> ... | (x,y) :: tl -> ...
(1)Thinkabouthowtobreakdowntheinputintocases:
let rec prods (xs : (int*int) list) : int list = ... | (x,y) :: tl -> ... prods tl ...
(2)Assumetherecursivecallonsmallerdataiscorrect.(3)Usetheresultoftherecursivecalltobuildcorrectanswer.
Thisassump&oniscalledtheInduc&onHypothesis.You’lluseittoproveyourprogram
correct.
56
Anotherexample:zip
(* Given two lists of integers, return None if the lists are different lengths otherwise stitch the lists together to create Some of a list of pairs zip [2; 3] [4; 5] == Some [(2,4); (3,5)] zip [5; 3] [4] == None zip [4; 5; 6] [8; 9; 10; 11; 12] == None *)
(Giveitatry.)
57
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option =
58
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with
59
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> | ([], y::ys') -> | (x::xs', []) -> | (x::xs', y::ys') ->
60
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | ([], y::ys') -> | (x::xs', []) -> | (x::xs', y::ys') ->
61
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | ([], y::ys') -> None | (x::xs', []) -> None | (x::xs', y::ys') ->
62
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | ([], y::ys') -> None | (x::xs', []) -> None | (x::xs', y::ys') -> (x, y) :: zip xs' ys'
isthisok?
63
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | ([], y::ys') -> None | (x::xs', []) -> None | (x::xs', y::ys') -> (x, y) :: zip xs' ys'
No!zipreturnsalistop,on,notalist!WeneedtomatchitanddecideifitisSomeorNone.
64
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | ([], y::ys') -> None | (x::xs', []) -> None | (x::xs', y::ys') -> (match zip xs' ys' with None -> None | Some zs -> (x,y) :: zs)
Isthisok?
65
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | ([], y::ys') -> None | (x::xs', []) -> None | (x::xs', y::ys') -> (match zip xs' ys' with None -> None | Some zs -> Some ((x,y) :: zs))
66
Anotherexample:zip
let rec zip (xs : int list) (ys : int list) : (int * int) list option = match (xs, ys) with | ([], []) -> Some [] | (x::xs', y::ys') -> (match zip xs' ys' with None -> None | Some zs -> Some ((x,y) :: zs)) | (_, _) -> None
Cleanup.Reorganizethecases.PaLernmatchingproceedsinorder.
67
Abadlistexample
let rec sum (xs : int list) : int = match xs with | hd::tl -> hd + sum tl
68
Abadlistexample
let rec sum (xs : int list) : int = match xs with | hd::tl -> hd + sum tl
# Characters 39-78: ..match xs with hd :: tl -> hd + sum tl.. Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: [] val sum : int list -> int = <fun>
69
INSERTIONSORT
70
RecallInser,onSort
• Atanypointduringtheinser,onsort:– someini,alsegmentofthearraywillbesorted– therestofthearraywillbeinthesame(unsorted)orderasitwasoriginally
-5 -2 3 -4 10 6 7
sorted unsorted
71
RecallInser,onSort
• Atanypointduringtheinser,onsort:– someini,alsegmentofthearraywillbesorted– therestofthearraywillbeinthesame(unsorted)orderasitwasoriginally
• Ateachstep,takethenextiteminthearrayandinsertitinorderintothesortedpor,onofthelist
-5 -2 3 -4 10 6 7
sorted unsorted
-5 -4 -2 3 10 6 7
sorted unsorted
72
Inser,onSortWithLists• Thealgorithmissimilar,exceptinsteadofonearray,wewill
maintaintwolists,asortedlistandanunsortedlist
• We'llfactorthealgorithm:– afunc,ontoinsertintoasortedlist– asor,ngfunc,onthatrepeatedlyinserts
-5 -2 3 -4 10 6 7
sorted unsorted
list1: list2:
73
Insert
(* insert x in to sorted list xs *) let rec insert (x : int) (xs : int list) : int list =
74
Insert
(* insert x in to sorted list xs *) let rec insert (x : int) (xs : int list) : int list = match xs with | [] -> | hd :: tl -> afamiliarpaLern:
analyzethelistbycases
75
Insert
(* insert x in to sorted list xs *) let rec insert (x : int) (xs : int list) : int list = match xs with | [] -> [x] | hd :: tl ->
insertxintotheemptylist
76
Insert
(* insert x in to sorted list xs *) let rec insert (x : int) (xs : int list) : int list = match xs with | [] -> [x] | hd :: tl -> if hd < x then hd :: insert x tl
buildanewlistwith:• hdatthebeginning• theresultofinser,ngxinto
thetailofthelistawerwards
77
Insert
(* insert x in to sorted list xs *) let rec insert (x : int) (xs : int list) : int list = match xs with | [] -> [x] | hd :: tl -> if hd < x then hd :: insert x tl else x :: xs
putxonthefrontofthelist,therestofthelistfollows
78
Inser,onSort
type il = int list insert : int -> il -> il (* insertion sort *) let rec insert_sort(xs : il) : il =
79
Inser,onSort
type il = int list insert : int -> il -> il (* insertion sort *) let rec insert_sort(xs : il) : il = let rec aux (sorted : il) (unsorted : il) : il = in
80
Inser,onSort
type il = int list insert : int -> il -> il (* insertion sort *) let rec insert_sort(xs : il) : il = let rec aux (sorted : il) (unsorted : il) : il = in aux [] xs
81
Inser,onSort
type il = int list insert : int -> il -> il (* insertion sort *) let rec insert_sort(xs : il) : il = let rec aux (sorted : il) (unsorted : il) : il = match unsorted with | [] -> | hd :: tl -> in aux [] xs
82
Inser,onSort
type il = int list insert : int -> il -> il (* insertion sort *) let rec insert_sort(xs : il) : il = let rec aux (sorted : il) (unsorted : il) : il = match unsorted with | [] -> sorted | hd :: tl -> aux (insert hd sorted) tl in aux [] xs
83
ASHORTJAVARANT
84
Defini,onandUseofJavaPairs
Whatcouldgowrong?
public class Pair { public int x; public int y; public Pair (int a, int b) { x = a; y = b; } }
public class User { public Pair swap (Pair p1) { Pair p2 = new Pair(p1.y, p1.x); return p2; } }
85
APaucityofTypes
Theinputp1toswapmaybenullandweforgottocheck.
Javahasnowaytodefineapairdatastructurethatisjustapair.
public class Pair { public int x; public int y; public Pair (int a, int b) { x = a; y = b; } }
public class User { public Pair swap (Pair p1) { Pair p2 = new Pair(p1.y, p1.x); return p2; } }
86
Howmanystudentsintheclasshaveseenanaccidentalnullpointerexcep&onthrownintheirJavacode?
FromJavaPairstoOCamlPairs
type java_pair = (int * int) option
InOCaml,ifapairmaybenullitisapairop,on:
87
FromJavaPairstoOCamlPairs
let swap_java_pair (p:java_pair) : java_pair = let (x,y) = p in (y,x)
type java_pair = (int * int) option
InOCaml,ifapairmaybenullitisapairop,on:
Andifyouwritecodelikethis:
88
FromJavaPairstoOCamlPairs
let swap_java_pair (p:java_pair) : java_pair = let (x,y) = p in (y,x)
type java_pair = (int * int) option
InOCaml,ifapairmaybenullitisapairop,on:
Andifyouwritecodelikethis:
# … Characters 91-92: let (x,y) = p in (y,x);; ^ Error: This expression has type java_pair = (int * int) option but an expression was expected of type 'a * 'b
Yougetahelpfulerrormessagelikethis:
89
FromJavaPairstoOCamlPairs
type java_pair = (int * int) option
let swap_java_pair (p:java_pair) : java_pair = match p with | Some (x,y) -> Some (y,x)
Andwhatifyouwereupat3amtryingtofinishyourCOS326assignmentandyouaccidentallywrotethefollowingsleep-deprived,brain-deadstatement?
90
FromJavaPairstoOCamlPairs
type java_pair = (int * int) option
let swap_java_pair (p:java_pair) : java_pair = match p with | Some (x,y) -> Some (y,x)
Andwhatifyouwereupat3amtryingtofinishyourCOS326assignmentandyouaccidentallywrotethefollowingsleep-deprived,brain-deadstatement?
..match p with | Some (x,y) -> Some (y,x) Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: None
OCamltotherescue!
91
FromJavaPairstoOCamlPairs
type java_pair = (int * int) option
let swap_java_pair (p:java_pair) : java_pair = match p with | Some (x,y) -> Some (y,x)
Andwhatifyouwereupat3amtryingtofinishyourCOS326assignmentandyouaccidentallywrotethefollowingsleep-deprived,brain-deadstatement?
Aneasyfix!
let swap_java_pair (p:java_pair) : java_pair = match p with | None -> None | Some (x,y) -> Some (y,x)
92
FromJavaPairstoOCamlPairs
Moreover,yourpairsareprobablyalmostnevernull!
Defensiveprogramming&alwayscheckingfornullis
93
FromJavaPairstoOCamlPairs
Therejustisn'talwayssome"goodthing"forafunc,ontodowhenitreceivesa
badinput,likeanullpointer
InOCaml,alltheseissuesdisappearwhenyouusethepropertypeforapairandthattypecontainsno"extrajunk”
OnceyouknowOCaml,itishardtowriteswapincorrectlyYourbullet-proofcodeismuchsimplerthaninJava.
type pair = int * int
let swap (p:pair) : pair = let (x,y) = p in (y,x)
94
SummaryofJavaPairRant
Javahasapaucityoftypes– Thereisnotypetodescribejustthepairs– Thereisnotypetodescribejustthetriples– Thereisnotypetodescribethepairsofpairs– Thereisnotype…
OCamlhasmanymoretypes– useop,onwhenthingsmaybenull– donotuseop,onwhenthingsarenotnull– OCamltypesdescribedatastructuresmoreprecisely
• programmershavefewercasestoworryabout• en,reclassesoferrorsjustgoaway• typecheckingandpaLernanalysishelppreventprogrammersfromeverforgeyngaboutacase
95
SummaryofJavaPairRant
Javahasapaucityoftypes– Thereisnotypetodescribejustthepairs– Thereisnotypetodescribejustthetriples– Thereisnotypetodescribethepairsofpairs– Thereisnotype…
OCamlhasmanymoretypes– useop,onwhenthingsmaybenull– donotuseop,onwhenthingsarenotnull– ocamltypesdescribedatastructuresmoreprecisely
• programmershavefewercasestoworryabout• en,reclassesoferrorsjustgoaway• typecheckingandpaLernanalysishelppreventprogrammersfromeverforgeyngaboutacase
SCORE:OCAML1,JAVA0
96
Exampleproblemstoprac,ce• Writeafunc,ontosumtheelementsofalist
– sum[1;2;3]==>6• Writeafunc,ontoappendtwolists
– append[1;2;3][4;5;6]==>[1;2;3;4;5;6]• Writeafunc,ontoreversealist
– rev[1;2;3]==>[3;2;1]• Writeafunc,ontoturnalistofpairsintoapairoflists
– split[(1,2);(3,4);(5,6)]==>([1;3;5],[2;4;6])• Writeafunc,onthatreturnsallprefixesofalist
– prefixes[1;2;3]==>[[];[1];[1;2];[1;2;3]]• suffixes…
97