CSE341 Notes for Wednesday, 4/21/10

I began by discussing the next programming assignment. I won't repeat that here since the assignment writeup contains the essential information.

Then I turned to a new topic: the option type. It solves a certain problem that comes up in programming. Consider the problem of reading data from a file. Generally there is data to read, but what about when you reach the end of the file? What should be returned in that case? I asked people if they knew what happens when you call the Scanner class' method nextLine when end of file is true. Someone pointed out that it throws an exception. I asked if people knew what the built-in System.in variable returns when you call its read method. Nobody seemed to know. I said that the read method returns a value of type int. When you reach end of file, the method returns -1 as a way to say, "There is no more legal input to read." There is another reading class in the Java class libraries known as BufferedReader that has a readLine method. It returns null when you attempt to read beyond the end of a file.

None of these approaches is particularly elegant. What we want is the ability to return different things in different cases. If reading succeeds, we return a value. If it fails, we return a value that would correspond to "nothing". This is what the option type is used for in ML.

As Ullman explains in chapter 4, the TextIO structure has a function called openIn that can be used to open a text file. Once you do that, you can use the function readLine to read individual lines. The return type of readLine is a "string option". That means that sometimes it returns a string, sometimes it doesn't. The two constructors that are used for the option type are NONE and SOME. In fact, you can ask about these in the ML interpreter:

        - NONE;
        val it = NONE : 'a option
        - SOME;
        val it = fn : 'a -> 'a option
The constructor NONE is like our color constants. It doesn't have a value associated with it. But the SOME constructor takes a value of type 'a and returns a 'a option. Here are some examples:

        - SOME 3;
        val it = SOME 3 : int option
        - SOME "hello";
        val it = SOME "hello" : string option
        - SOME 45.8;
        val it = SOME 45.8 : real option
It takes a while for people to get used to the option type because languages like Java don't have anything that is like it. To extract a value from an option, you can call the function valOf. So you might say:

        - val x = SOME 82;
        val x = SOME 82 : int option
        - valOf(x);
        val it = 82 : int
We often don't need the valOf function because we instead use pattern matching to define a function that operates on an option, as in: fun f(NONE) = 0 | f(SOME n) = 2 * n; The option type is predefined in ML, but it's definition is fairly simple:

        datatype 'a option = NONE | SOME of 'a;

Stuart Reges
Last modified: Wed Apr 21 17:28:31 PDT 2010