Home > Documents > Thinking Induc,vely · 2017. 9. 20. · let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -....

# Thinking Induc,vely · 2017. 9. 20. · let (x1,y1) = p1 in let (x2,y2) = p2 in sqrt (square (x2 -....

Date post: 11-Dec-2020
Category:
View: 8 times
97
Thinking Induc,vely COS 326 David Walker Princeton University slides copyright 2017 David Walker permission granted to reuse these slides for non-commercial educa,onal purposes
Transcript

ThinkingInduc,vely

COS326DavidWalker

PrincetonUniversity

•  Programstyleguide:–  hLp://www.cs.princeton.edu/~cos326/style.php

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)) ;;

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))

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

–  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 :: _ ->

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 -> ...

let rec prods (xs : (int*int) list) : int list = ... | (x,y) :: tl -> ... prods tl ...

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

let rec sum (xs : int list) : int = match xs with | hd::tl -> hd + sum tl

68

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

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

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)

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)

..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)

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

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

95

SummaryofJavaPairRant

Javahasapaucityoftypes–  Thereisnotypetodescribejustthepairs–  Thereisnotypetodescribejustthetriples–  Thereisnotypetodescribethepairsofpairs–  Thereisnotype…

OCamlhasmanymoretypes–  useop,onwhenthingsmaybenull–  donotuseop,onwhenthingsarenotnull–  ocamltypesdescribedatastructuresmoreprecisely

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

Recommended