90 likes | 212 Vues
This text delves into the concept of first-class functions in Scala, explaining how functions can be treated as values—passed as parameters or returned as results. It outlines higher-order functions, which enhance the power of functional programming by allowing functions to accept other functions as arguments. Using examples, the text illustrates how to define and implement various functions (such as sum, square, and power functions) and demonstrates recursion effectively. Additionally, it introduces case classes and patterns for summing elements in a custom list structure, emphasizing generalization in function use.
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 }