90 likes | 202 Views
Patterns, Case Classes, and First Order Functions (Oh My). UMBC CMSC 331. First-Class Functions. A function in Scala is a first-class value Like any other value, it may be passed as a parameter or returned as a result.
E N D
Patterns, Case Classes, and First Order Functions (Oh My) UMBC CMSC 331
First-Class Functions • A function in Scala is a first-class value • Like any other value, it may be passed as a parameter or returned as a result. • Functions which take other functions as parameters or return them as results are called higher-order functions.
Examples scala> def sumInts(a: Int, b: Int): Int = | if (a > b) 0 else a + sumInts(a + 1, b) sumInts: (Int,Int)Int What does this guy do? def square(x: Int): Int = x * x def sumSquares(a: Int, b: Int): Int = if (a > b) 0 else square(a) + sumSquares(a + 1, b) Or these def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x - 1) def sumPowersOfTwo(a: Int, b: Int): Int = if (a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a + 1, b)
What is the Pattern? • Each time we are looping applying a function and adding the result • Why not generalize and pass in the function? That’s the idea behind a higher order function. def sum(f: Int => Int, a: Int, b: Int): Int = if (a > b) 0 else f(a) + sum(f, a + 1, b)
Suppose we have the following functions def id(x: Int): Int = x def square(x: Int): Int = x * x def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x - 1)
How Can the Originals Be Recoded? def sumInts(a: Int, b: Int): Int = sum(id, a, b) def sumSquares(a: Int, b: Int): Int = sum(square, a, b) def sumPowersOfTwo(a: Int, b: Int): Int = sum(powerOfTwo, a, b)
Consider the following Simple Case Classes abstract class Ilist case class isEmpty extends Ilist case class ICell (front: Int, rest : Ilist) extends Ilist How Can One Sum Over the Elements?
Case Classes and Patterns scala> def sum (s: Int => Int, l : Ilist) : Int = l match { | case ICell (f,r) => s(f) + sum(s,r) | case isEmpty => 0 | | } sum: ((Int) => Int,Ilist)Int
Can Sum be made more General? • Can the Sum be replace by an arbitrary function? • Yes, regard the function below. def fold (f: (Int , Int) => Int , l : Ilist, v : Int) : Int = l match { case ICell (front, ICell (next , rest )) => fold ( f, ICell (f (front, next) , rest ), v ) case ICell (front , isEmpty) => f ( front,v) case isEmpty => v }