This preview shows pages 1–3. Sign up to view the full content.
This preview has intentionally blurred sections. Sign up to view the full version.View Full Document
Unformatted text preview: CS 3110 Lecture 4 Variant types and polymorphism Variant types Lists are very useful, but it turns out they are not really as special as they look. We can implement our own lists, and other more interesting data structures, such as binary trees. In recitation you should have seen some simple examples of variant types sometimes known as algebraic datatypes or just datatypes . Variant types provide some needed power: the ability to have a variable that contains more than one kind of value. Unlike tuple types and function types, but like record types, variant types cannot be anonymous; they must be declared with their names. Suppose we had a variable that could be contain yes, no, or maybe. Its type could be declared as a variant type: # type answer = Yes | No | Maybe;; type answer = Yes | No | Maybe # let x: answer = Yes;; val x: ans = Yes The variant type is declared with a set of constructors that describe the possible ways to make a value of that type. In this case, we have three constructors: Yes , No , and Maybe . Constructor names must start with a capital letter, and all other names in OCaml cannot start with a capital. The different constructors can also carry values with them. For example, suppose we want a type that can either be a 2D point or a 3D point. It can be declared as follows: type eitherPoint = TwoD of float * float | ThreeD of float * float * float Some examples of values of type eitherPoint are: TwoD(2.1, 3.0) and ThreeD(1.0, 0.0, -1.0) . Suppose we have a value of type eitherPoint . We need to find out which constructor it was made from in order to get at the point data inside. This can be done using matching: let p: eitherPoint = ... in match p with TwoD(x, y) -> ... | ThreeD(x, y, z) -> ... Variant type syntax We use X as a metavariable to represent the name of a constructor, and T to represent the name of a type. Optional syntactic elements are indicated by brackets . Then a variant type declaration looks like this in general: type T = X 1 [ of t 1 ] | ... | X n [ of t n ] Variant types introduce new syntax for terms e , patterns p , and values v : e ::= ... | X ( e ) | match e with p 1-> e 1 | ... | p n-> e n p ::= X | X ( x 1 : t 1 ... , x n : t n ) v ::= c | ( v 1 ,..., v n ) | fun p-> e | X ( v ) Note that the vertical bars in the expression " match e with p 1-> e 1 | ... | p n-> e n " are part the syntax of this construct; the other vertical bars (|) are part of the BNF notation. We can use variant types to define many useful data structures. In fact, the bool is really just a variant type with constructors named true and false . Implementing integer lists We can write our own version of lists using variant types. Suppose we want to define values that act like linked lists of integers. A linked list is either empty, or it has an integer followed by another list containing the rest of the list elements. This leads to a very natural variant type declaration: type intlist = Nil | Cons of (int * intlist) This type has two constructors,...
View Full Document
This note was uploaded on 10/25/2009 for the course PHYS 2214 at Cornell University (Engineering School).