sum of product datatypes in sml
play

Sum-of-Product Datatypes in SML and triangles so that we can do - PowerPoint PPT Presentation

Mo;va;ng example: geometric figures Suppose we want to represent geometric figures like circles, rectangles, Sum-of-Product Datatypes in SML and triangles so that we can do things like calculate their perimeters, scale them, etc. (Dont worry


  1. Mo;va;ng example: geometric figures Suppose we want to represent geometric figures like circles, rectangles, Sum-of-Product Datatypes in SML and triangles so that we can do things like calculate their perimeters, scale them, etc. (Don’t worry about drawing them!) CS251 Programming Languages These are so-called sum of products data: • Circle, Rec, and Tri are tags that dis;nguish which one in a sum Fall 2017 • The numeric children of each tag are the product associated with that tag. Lyn Turbak How would you do this in Java? In Python? Department of Computer Science Wellesley College Sum-of-Product Datatypes in SML 2 SML’s datatype for Sum-of-Product types Func;ons on datatype via paRern matching � (* Return perimeter of figure *) fun perim (Circ r) = 2.0 * Math.pi * r | perim (Rect(w,h)) = 2.0 * (w + h) | perim (Tri(s1,s2,s3)) = s1 + s2 + s3 (* Scale figure by factor n *) fun scale n (Circ r) = Circ (n * r) � datatype figure = | scale n (Rect(w,h)) = Rect (n*w, n*h) Circ of real (* radius *) | scale n (Tri(s1,s2,s3)) = Tri (n*s1, n*s2, n*s3) | Rect of real * real (* width, height *) | Tri of real * real * real (* side1, side2, side3 *) � - val perims = map perim figs val perims = [6.28318530718,10.0,15.0] : real list val figs = [Circ 1.0, Rect (2.0,3.0), Tri(4.0,5.0,6.0)] (* List of sample figures *) - val scaledFigs = map (scale 3.0) figs val scaledFigs = [Circ 3.0,Rect (6.0,9.0), val circs = map Circ [7.0, 8.0, 9.0] Tri (12.0,15.0,18.0)] : figure list (* List of three circles *) Sum-of-Product Datatypes in SML 3 Sum-of-Product Datatypes in SML 4

  2. Op;ons Sample Use of Op;ons SML has a built-in option datatype defined as follows: - fun into_100 n = if (n = 0) then NONE else SOME (100 div n); val into_100 = fn : int -> int option datatype 'a option = NONE | SOME of 'a - List.map into_100 [5, 3, 0, 10]; val it = [SOME 20,SOME 33,NONE,SOME 10] : int option list - NONE - fun addOptions (SOME x) (SOME y) = SOME (x + y) val it = NONE : 'a option = | addOptions (SOME x) NONE = NONE = | addOptions NONE (SOME y) = NONE - SOME 3; = | addOptions NONE NONE = NONE; val it = SOME 3 : int option val addOptions = fn : int option -> int option -> int option - SOME true; - addOptions (into_100 5) (into_100 10); val it = SOME true : bool option val it = SOME 30 : int option - addOptions (into_100 5) (into_100 0); val it = NONE: int option Sum-of-Product Datatypes in SML 5 Sum-of-Product Datatypes in SML 6 Op;ons and List.find Thinking about op;ons (* List.find : ('a -> bool) -> 'a list -> 'a option *) What problem do op;ons solve? - List.find ( fn y => (y mod 2) = 0) [5,8,4,1]; val it = SOME 8 : int option How is the problem solved in other languages? - List.find ( fn z => z < 0) [5,8,4,1]; val it = NONE : int option Sum-of-Product Datatypes in SML 7 Sum-of-Product Datatypes in SML 8

  3. Crea;ng our own list datatype Binary Trees � datatype 'a mylist = Nil | Cons of 'a * 'a mylist val ints = Cons(1, Cons(2, Cons(3, Nil))) (* : int mylist *) val strings = Cons("foo", Cons ("bar", Cons ("baz", Nil))) (* : strings mylist *) fun myMap f Nil = Nil | myMap f (Cons(x,xs)) = Cons(f x, myMap f xs) (* : ('a -> 'b) -> 'a mylist -> 'b mylist *) val incNums = myMap ( fn x => x + 1) ints (* val incNums= Cons (2,Cons (3,Cons (4,Nil))) : int mylistval *) val myStrings = myMap ( fn s => "my " ^ s) strings (* val myStrings = Cons ("my foo", Cons ("my bar", Cons ("my baz",Nil))): string mylist *) Sum-of-Product Datatypes in SML 9 Sum-of-Product Datatypes in SML 10 SML bintree datatype for Binary Trees bintree can have any type of element datatype 'a bintree = val string_tree = Node(Node (Leaf,"like",Leaf), Leaf "green", | Node of 'a bintree * 'a * 'a bintree Node (Node (Leaf,"and",Leaf), (* left subtree, value, right subtree *) "eggs", Node (Leaf,"ham",Leaf))) val int_tree= Node(Node(Leaf,2,Leaf), 4, Node(Node(Leaf, 1, Node(Leaf, 5, Leaf)), 6, Node(Leaf, 3, Leaf))) Sum-of-Product Datatypes in SML 11 Sum-of-Product Datatypes in SML 12

  4. Coun;ng nodes in a binary tree Your turn: height (* val height = fn : 'a bintree -> int *) (* Returns the height of a binary tree. *) (* Note: Int.max returns the max of two ints *) fun num_nodes Leaf = 0 fun height Leaf = 0 | num_nodes (Node(l,v,r)) = 1 + (num_nodes l) + (num_nodes r) | height (Node(l,v,r)) = 1 + Int.max(height l, height r) - num_nodes int_tree; val it = 6 : int - height int_tree; val it = 4 : int - num_nodes string_tree; val it = 5 : int - height string_tree; val it = 3 : int Sum-of-Product Datatypes in SML 13 Sum-of-Product Datatypes in SML 14 Your turn: sum_nodes Your turn: inlist This returns a list of elements as they are Encountered in an in-order traversal of a tree. We could also list them via a pre-order or post-order traversal. (* val inlist = fn : 'a bintree -> 'a list *) (* val sum_nodes = fn : int bintree -> int *) (* Returns a list of the node values in in-order *) (* Returns the sum of node values in binary tree of ints *) fun inlist Leaf = [] fun sum_nodes Leaf = 0 | inlist (Node(l,v,r)) = (inlist l) @ [v] @ (inlist r) | sum_nodes (Node(l,v,r)) = (sum_nodes l) + v + (sum_nodes r) - inlist int_tree; - sum_nodes int_tree; val it = [2,4,1,5,6,3] : int list val it = 21 : int - inlist string_tree; val it = ["like","green","eggs","and","ham"] : string list Sum-of-Product Datatypes in SML 15 Sum-of-Product Datatypes in SML 16

  5. Your turn: map_tree Your turn: fold_tree (* val map_tree = fn : ('a -> 'b) -> 'a bintree -> 'b bintree *) (* val fold_tree = fn : ('b * 'a * 'b -> 'b) -> 'b (* maps function over every node in a binary tree *) -> 'a bintree -> 'b *) (* binary tree accumulation *) fun map_tree f Leaf = Leaf | map_tree f (Node(l,v,r)) = Node(map_tree f l, f v, map_tree f r) fun fold_tree comb leafval Leaf = leafval | fold_tree comb leafval (Node(l,v,r)) = comb(fold_tree comb leafval l, v, fold_tree comb leafval r) - map_tree (fn x => x*2) int_tree; val it = Node (Node (Leaf,4,Leaf),8, Node (Node (Leaf,2,Node (Leaf,10,Leaf)),12, - fold_tree (fn (lsum,v,rsum) => lsum + v + rsum) 0 int_tree; Node (Leaf,6,Leaf))) : int bintree val it = 21 : int - map_tree (fn s => String.sub(s,0)) string_tree; - fold_tree (fn (lstr,v,rstr) => lstr ^ v ^ rstr) " " string_tree; val it = Node (Node (Leaf,#"l",Leaf),#"g", val it = " like green eggs and ham " : string Node (Node (Leaf,#"e",Leaf),#"a", Node (Leaf,#"h",Leaf))) : char bintree Sum-of-Product Datatypes in SML 17 Sum-of-Product Datatypes in SML 18 Binary Search Trees (BSTs) on integers You turn: Binary Search Tree inser;on fun singleton v = Node(Leaf, v, Leaf) (* val insert: int bintree -> int -> int bintree *) fun insert x Leaf = singleton x | insert x (t as (Node(l,v,r))) = if x = v then t else if x < v then Node(insert x l, v, r) else Node(l, v, insert x r) fun listToTree xs = foldl (fn (x,t) => insert x t) Leaf xs - val test_bst = listToTree [4,2,3,6,1,7,5]; val test_bst = Node (Node (Node (Leaf,1,Leaf), 2, Node (Leaf,3,Leaf)), 4, Node (Node (Leaf,5,Leaf), 6, Node (Leaf,7,Leaf))) : int bintree Sum-of-Product Datatypes in SML 19 Sum-of-Product Datatypes in SML 20

  6. Your turn: Binary Search Tree membership Balanced Trees (PS7) BSTs are not guaranteed to be balanced. (val member: ''a -> ''a bintree -> bool *) But there are other tree data structures that do guarantee balance: fun member x Leaf = AVL trees, Red/Black trees, 2-3 trees, 2-3-4 trees. | member x (Node(l,v,r)) = In PS6 you will experiment with 2-3 trees. -  val test_member = map ( fn i => (i, member i test_bst)) [0,1,2,3,4,5,6,7,8]; val it = [(0,false),(1,true),(2,true),(3,true), (4,true),(5,true),(6,true),(7,true), (8,false)] : (int * bool) list Sum-of-Product Datatypes in SML 21 Sum-of-Product Datatypes in SML 22

Recommend


More recommend