CIS-3030 Homework #2: Pairs, Lists and Patterns

Due: Wednesday, February 6, 2019

Read Sections 17.5 (page 360) in Programming in Scala. Note that the example given is imperative (it uses mutable vars). We are using tuples in a strictly functional way for now. In Chapter 3, read "Step 8" about lists and "Step 9" about tuples. Chapter 6 (page 307) gives much more detail about lists. Pay particular attention to Sections 16.1 through 16.6.

Create a file named Hw02.scala that contains the following object definition. In your version, implement the methods!

Put the file in the src/main/scala folder where your sbt sandbox project is located (create that folder if necessary). You can use the "compile" command in sbt interactively to compile (or recompile) the code. When you start the REPL, sbt will automatically include the compiled code in the class path. Thus you should be able to directly run the various methods by simply qualifying their names with Hw02 (for example: Hw02.sumAndProductA(5)). You don't need to load the code into the REPL manually.

 object Hw02 {

  // Returns a pair with the components swapped relative to the input pair. For example:
  // pairSwap( (1, 2) ) should return (2, 1). Use the ._1 and ._2 notation to access the
  // input pair component values. Notice that this method is generic; it can swap pairs of
  // any type.
  def pairSwap[A, B](p: (A, B)): (B, A) = ???

  
  // An alternative way of writing a pair is to use -> instead of a comma. For example:
  // ("Peter" -> 102.5) is the same as ("Peter", 102.5) and has type (String, Double).
  // This notation emphasizes the idea of using a pair to form an association from a "key" to
  // a corresponding "value." It is a syntactic variation only. The result is still a pair.

  // Take two pairs and returns a pair of associations where the first component of the first
  // pair is associated with the first component of the second one, and similarly for the
  // second components. For example buildAssociations( (1, 2), ("Peter", "Jill") ) should
  // return ( (1 -> "Peter"), (2 -> "Jill") ). Use pattern matching to deconstruct the two
  // input pairs. Use the -> operator when building the result to make the intent clear.
  def buildAssociations[A, B](x: (A, A), y: (B, B)): ((A, B), (A, B)) = ???
  

  // Computes the sum and product of all intergers from 1 through n and returns both results as
  // a pair. For example: sumAndProductA(5) should return (15, 120). For this version of
  // the method define two helper methods (locally inside this method), one for computing the
  // sum and one for computing the product. Use the helper methods to compute the final result.
  def sumAndProductA(n: Int): (Int, Int) = ???

  // Does the same thing as the method above, except this time use recusion directly with no
  // helper methods.
  def sumAndProductB(n: Int): (Int, Int) = ???


  // Computes the sum and product of a list of elements, returning both results as a pair (like
  // above). For example:
  //
  // val myList = List(2, 4, 6)
  // listSumAndProduct(myList) == (12, 48)
  //
  // Use a match expression with list patterns and recursion.
  def listSumAndProduct(myList: List[Int]): (Int, Int) = ???

  
  // "Zips" two lists into a list of pairs. For example:
  //
  // val myList1 = List(1, 2, 3)
  // val myList2 = List("x", "y", "z")
  // zip(myList1, myList2) == List( (1, "x"), (2, "y"), (3, "z") )
  //
  // If the lists have unequal length only the corresponding items are zipped. The rest are
  // ignored.
  //
  // Hint: Pattern match on (list1, list2) and use pair/list combination patterns like
  // (Nil, Nil) and (x::xs, y::ys) in the case expressions. Don't be afraid to write complex
  // patterns! The power of pattern matching is that it can handle structures of arbitrary
  // complexity.
  //
  def zip[A, B](list1: List[A], list2: List[B]): List[(A, B)] = ???

  
  // "Unzips" a list of pairs into a pair of lists. For example:
  //
  // val myList = List( (1, "x"), (2, "y"), (3, "z") )
  // unzip(myList) returns (List(1, 2, 3), List("x", "y", "z"))
  //
  // Hint: Match the input list against the pattern (first,second)::xs. Use recursion to
  // unzip xs into two lists. Then cons first to the front of the first list and second to the
  // front of the second list. Return the result as a pair.
  def unzip[A, B](list: List[(A, B)]): (List[A], List[B]) = ???
}  
    

Submit your file Hw02.scala (put your name in comments).


Last Revised: 2019-01-29
© Copyright 2019 by Peter C. Chapin <pchapin@vtc.edu>