CMSC330Data types, exceptions, and modulesLast time• Ocaml closures and curryingThis time• Finishing up Ocaml– Data types– Exceptions– ModulesOcaml data• So far, we’ve seen the following kinds of data– Basic types (int, float, char, string)– Lists• One kind of data structure• A list is either [ ] or h::t, deconstructed with pattern matching– Tuples• Let you collect data together in fixed-size pieces– Functions• How can we build other data structures?– Building everything from lists and tuples is awkwardData types• Rect and Circle are type constructors– Here a shape is either a Rect or a Circletype shape =Rect of float * float (* width * length *)| Circle of float (* radius *)Data Types (cont.)• Use pattern matching to deconstructvalues– s is a shape– Do different things for s depending on its constructorlet area s =match s withRect (w, l) -> w *. l| Circle r -> r *. r *. 3.14area (Rect (3.0, 4.0))area (Circle 3.0)Data Types (cont.)• What's the type of l?shape list• What's the type of l's first element?shapetype shape =Rect of float * float (* width * length *)| Circle of float (* radius *)let l = [Rect (3.0, 4.0) ; Circle 3.0]Data Types Constructor• Constructors must begin with uppercase letter• The arity of a constructor – Is the number of arguments it takes– A constructor with no arguments is nullary• Example– Arity of None = 0– Arity of Some = 1type optional_int =None| Some of intPolymorphic Data Types• This option type can work with any kind of data– In fact, this option type is built into OCamltype optional_int =None| Some of intlet add_with_default a = functionNone -> a + 42| Some n -> a + nadd_with_default 3 None (* 45 *)add_with_default 3 (Some 4) (* 7 *)Recursive Data Types• We can build up lists this way– Won’t have nice [1; 2; 3] syntax for this kind of listtype 'a list =Nil| Cons of 'a * 'a listlet rec len = functionNil -> 0| Cons (_, t) -> 1 + (len t)len (Cons (10, Cons (20, Cons (30, Nil))))Data Type Representations• Values in a data type are stored 1. Directly as integers 2. As pointers to blocks inthe heaptype t =A of int| B| C of int * int| DExercise: A Binary Tree Data Type• Write type bin_tree for binary trees over int– Trees should be ordered (binary search tree)Ocaml exceptionsexception My_exception of intlet f n =if n > 0 thenraise (My_exception n)elseraise (Failure "foo")let bar n =tryf nwith My_exception n ->Printf.printf "Caught %d\n" n| Failure s ->Printf.printf "Caught %s\n" sOcaml exceptions (cont.)• Exceptions are declared with exception• Exceptions may take arguments– Just like type constructors– May also be nullary• Catch exceptions with try...with...– Pattern-matching can be used in with– If an exception is uncaught• Current function exits immediately• Control transfers up the call chain • Until the exception is caught, or reaches the top levelOcaml exceptions (cont.)• Exceptions may be thrown by I/O statements– Common way to detect end of file– Need to decide how to handle exception• Exampletry(input_char stdin) (* reads 1 char *)with End_of_file -> 0 (* return 0? *)tryread_line () (* reads 1 line *)with End_of_file -> “” (* return “”? *)Modules• So far, most everything we’ve defined – Has been at the “top-level” of OCaml– This is not good software engineering practice• A better idea– Use modules to group together associated • Types, functions, and data– Avoid polluting the top-level with unnecessary stuff• For lots of sample modules– See the OCaml standard libraryModularity and Abstraction• Another reason for creating a module – So we can hide details– Example• Build a binary tree module• Hide exact representation of binary trees– This is also good software engineering practice• Prevents clients from relying on details that may change• Hides unimportant information• Promotes local understanding (clients can’t inject arbitrary data structures, only ones our functions create)Modularity• Definition– Extent to which a computer program is composed of separate parts– Higher degree of modularity is better• Modular programming– Programming techniques that increase modularity• Interface vs. implementation• Modular programming languages– Explicit support for modules– Ada, Fortran, ML, Modula-2, Python, Ruby, OCamlCreating a module in Ocamlmodule Shapes =structtype shape =Rect of float * float (* wid*len *)| Circle of float (* radius *)let area = functionRect (w, l) -> w *. l| Circle r -> r *. r *. 3.14let unit_circle = Circle 1.0end;;Creating a module in Ocaml (cont.)module Shapes =structtype shape = …let area = …let unit_circle = …end;;unit_circle;; (* not defined *)Shapes.unit_circle;;Shapes.area (Shapes.Rect (3.0, 4.0));;open Shapes;; (* import names into curr scope *)unit_circle;; (* now defined *)Module Signaturesmodule type FOO =sigval add : int -> int -> intend;;module Foo : FOO =structlet add x y = x + ylet mult x y = x * yend;;Foo.add 3 4;; (* OK *)Foo.mult 3 4;; (* not accessible *)Entry in signatureSupply function typesGive type to moduleModule signatures (cont.)• Convention – Signatures to be all capital letters– This isn't a strict requirement, though• Items can be omitted from a module signature– This provides the ability to hide values• The default signature for a module hides nothing– You’ll notice this is what OCaml gives you if you just type in a module with no signature at the top-levelAbstract Types in signatures• Now definition of shape is hiddenmodule type SHAPES =sigtype shapeval area : shape -> floatval unit_circle : shapeval make_circle : float -> shapeval make_rect : float -> float -> shapeend;;module Shapes : SHAPES =struct...let make_circle r = Circle rlet make_rect x y = Rect (x, y)endAbstract Types in signatures (cont.)• How does this compare to modularity in...– C?– C++?– Java?# Shapes.unit_circle- : Shapes.shape = <abstr> (* OCaml won’t show impl *)# Shapes.Circle 1.0Unbound Constructor Shapes.Circle#Shapes.area (Shapes.make_circle 3.0)- : float = 29.5788#open Shapes;;# (* doesn’t make anything abstract accessible *).ml and .mli files• Put the signature in a foo.mli file, the structin a foo.ml file– Use the same names– Omit the sig...end and struct...endparts– The OCaml compiler will make a Foo module from theseExample – Ocaml module signaturestype shapeval area :
View Full Document