Problem Set 1: An introduction to SML

Due Wednesday, February 2, 2005, 11:00 pm.


The goal of this problem set is to expose you to as much of the SML language as possible while learning a bit about functional style programming. If you are not already familiar with SML, it may be a fair amount of new material, so please begin this problem set early.

Instructions: You will do this problem set by modifying the files found in ps1.zip and submitting these through CMS. All programs that you submit must compile. Programs that do not compile will receive an automatic zero. If you are having trouble getting your assignment to compile, please visit consulting hours. If you run out of time, it is better to comment out the parts that do not compile and hand in a file that compiles, rather than handing in a more complete file that does not compile. Also, please pay attention to style. Refer to the CS 312 style guide and lecture notes.

For each of the problems, you will modify an included source file. For functions that are not implemented, you should see something of the form

    raise Fail "Not implemented"

You should remove this text and replace it with the body of the function. We will test some of your code using an automated test script. Do not change published variable names, function names and types. Do not remove our delimiters. Pay careful attention to types.

There are six parts to this assignment.

Part 1: Posting to the newsgroup

Post a test message to cornell.test with the subject "CS312 Test".
DO NOT post test messages to the course newsgroup or you may be penalized.

Part 2: Expressions and Types

A. Provide the types of each of the following expressions, by modifying the included source file types.txt.

  1.  "hello"
    
  2. [ (2.5, #"h"), (3.1415, #"d"),  (42.2, #"z") ]
    
  3. (fn y:int => "312!", "312", (312.01, 312), 213)
    
  4. fn x => (fn y => (x - 1) > (y + 42))
    
  5. (fn (x, y) => case y of
                       0 => 1
                     | 312 => 2
                     | _ => 3) (92, 29)
    
  6. fn (a, c, d) => case c of
                         [] => a andalso (d = "hi")
                       | 312::xs => a
                       | _ => (d = "bye")
    
  7. let
      val a = 52
      val b = a::[29, 30, 31]
    in
      (b, a)
    end
    

B. Give expressions which have the following types:

  1.  int * bool -> int
  2.  char list * (bool -> int) * (int list list) 
  3.  int -> bool -> int
  4.  (char * (string list)) list
  5.  (bool * int -> string) * bool list

These are defined in the included file expressions.sig signature. Implement them by modifying the Expression structure found in file expressions.sml.

Part 3: Improving Style

The following functions can be found in the included file style.sml. Find parts which violate the style guide and fix them. At the top of each function add comments briefly describing the style problems you have identified. Do not change function names or function types.

  1.   fun funkyLogic(a:bool, b:bool):bool =
         if a = true then (if not (b = false) then true else false)
         else if not b then false
         else true
    
  2.    fun addList(l:int list):int =
         if null(l) then 0 else (hd l) + addList(tl l)
    
  3.    fun anotherFunction(x:string, y:int):int =
         case x of
           "hello" => 5
         | "bye" => 4
         | "harlan" => (case y of
                          1 => 23
                        | 0 => 99 - y
                        | _ => 365)
         | "cs312" => 42 + y
         | _ => ~20 * y
    
  4.    fun yetAnotherFunction(a:int*int*int, b:int):int =
         ((#2 a) * b) + (#1 a) - ((#3 a) * (#2 a))
    

Part 4: Value Declarations

Write the following val declarations by modifying the included file valDecl.sml. Do not change variable names or types.

  1. Bind the last name of the professor in all lower case letters to the variable professorName of type string.
  2. Bind your name, age, major and whether your favorite number is 42 to a record of type {name:string, age:int, major:string, favNum:bool} to the variable yourInfo.
  3. Bind the last letter in the alphabet (lowercase) to the the variable someLetter of type char.

Part 5: Function declarations

Write the following fun declarations by modifying the included file funDecl.sml. Do not change function names or function types.

  1. Write a function fact which takes one integer argument x and returns the factorial of that number.
      fun fact(x:int):int = raise Fail "Not implemented"
    
  2. Write a function that takes in an argument x of type position (defined below) and calculate that person's hourly salary in dollars, according to the following rules. Freshmen make $2, sophomores make $3, juniors make $4, seniors make $5. For master students, if their GPA is less than 2.0 they make $4 and otherwise they make $10. For PHDs, their hourly rate is $10 plus the number of years they have been a PHD student. The function should
  3. datatype position = FRESHMAN | SOPHOMORE | JUNIOR
                        | SENIOR | MS of real | PHD of int
    fun hourlyRate(x:position):int = raise Fail "Not implemented"
    
    The real associated with a MS is that person's GPA. The int associated with a PHD is the number of years they have been a PHD student.
  4. Write a function which takes a list of integers, and returns the result of multiplying all the integers in the list together. If the list is empty, the function should return 1.
      fun multiplyList(l:int list):int = raise Fail "Not implemented"
    

Part 6: Using the Basis Library

The basis library is one of the most helpful resources you have on your quest to learn SML. For this part of the assignment, you should browse The Standard ML Basis Library and then write short functions using the functions in the basis library. Modify the included file basislibrary.sml.

  1. Write a function that takes a string as an argument and returns a string which is the result of removing all the spaces from the input string.
    fun removeSpaces(s:string):string = raise Fail "Not implemented"
    
  2. Write a function which takes in tuple containing a pair of strings, and returns the sum of the lengths of the two strings.
    fun sumSizes(s1:string, s2:string):int = raise Fail "Not implemented"
    
  3. Write a function that takes a string s and changes all the upper case letters to lower case and all the lower case letters to upper case.
    fun flipCase(s:string):string = raise Fail "Not implemented"