Programmation appliquée en Scala

Copyright © Cay S. Horstmann 2015 Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License

Function definition with def

Recall: Higher-Order Functions

Factoring out the parameters

What Is ...

sum(square)(1,4)
  1. A syntax error—the argument to sum must be a paire of Ints
  2. Is equivalent to sumSquares(1,4)
  3. Is equivalent to sum(1,4)(square)
  4. Returns 30

Currying

Application of Currying: Type Inference

Folding

What Is ...

1.to(10).foldLeft("")(_ + _)
  1. "12345678910"
  2. "10987654321"
  3. 55
  4. Something else (syntax error, other result, ...)

More about Folding

Folding and Recursive Functions

Folding and Accumulation

Lab

Scary looking lab

Part 1: Currying

  1. Here is a function of computing the “maximum” string in a list that works for any ordering.
    def max(lst : Seq[String], less : (String, String) => Boolean) =
      lst.reduce((x, y) => if (less(x, y)) y else x)

    Make a call to max that yields the longest string in a sequence of strings. Important: Use _ for the string parameters in your less function.

  2. Now we'll make this generic. Don't worry—it won't hurt a bit:
    def max[T](lst : Seq[T], less : (T, T) => Boolean) =
        lst.reduce((x, y) => if (less(x, y)) y else x)

    What happens when you call max(lst, _ < _)?

  3. Ok, that didn't work so well. Currying to the rescue. Curry the max[T] function, exactly like mul2 above. What is the code for your revised function? What happens when you call max2(lst)(_ < _)?
  4. Why does the second approach work with _ parameters?

Part 2. Know When To Fold

  1. How do you compute `n!` with a fold?
    val fac = (n: Int) => ...
  2. How do you compute `n!` with a reduce?
  3. How do you compute `n!` with a recursive function?
  4. Now on to those subsets where your eyes probably glazed over. We want subsets(2) to be Vector(Vector(), Vector(1), Vector(2), Vector(1, 2)). How do you get that out of subsets(1), i.e. Vector(Vector(), Vector(1))?
  5. Ok, what's that in Scala? You are given a vector of vectors s and an integer n, and you want s together with the sequence obtained by adding n to all elements of s. Write a function that does that, and test it.
  6. Now write subsets by using foldLeft.
  7. It is also easy to write subsets as a recursive function. Try it!
  8. Complete and test the letterFrequencies function from the slide 12. What do you get for letterFrequencies("Mississippi")?

Part 3. Finish Phone Mnemonics

  1. Last time, we got stuck with repeatedly calling augment to get all ways of breaking up a string into substrings. For example, here are all substrings of "1234"
    augment(augment(augment(Vector(Vector("1")), '2'), '3'), '4')
    Get last week's worksheet from your buddy and copy over all you need to today's worksheet.
  2. Now we want this to work for arbitrary strings, not just "1234". Of course, we want to use foldLeft with augment. What is the seed value? And to what sequence do you apply foldLeft?
  3. Implement val substrings = (s: String) => .... What is substrings("2728")?
  4. Note that's a vector of Vector[String]. The shining achievement of last week's lab was the function wordsForDigitSequence that found all words for such a sequence. What do you get when you call
    substrings("2728").map(wordsForDigitsSequence)
  5. Ok, that's not quite what we want. How do you fix it?
  6. Now implement val phoneMnemonics = (digits: String) => ... that does this for any string of digits, not just "2728". What is phoneMnemonics("7225247386")? (You can change the cutoff limit of the worksheet in the preferences to see all solutions.)