jo.doubleName res4: String = JoJo Function: (args ) => expression scala> val mirror = (name: String) => name + name.reverse mirror: String => String = scala> mirror("Dave") res6: String = DaveevaD 3"> jo.doubleName res4: String = JoJo Function: (args ) => expression scala> val mirror = (name: String) => name + name.reverse mirror: String => String = scala> mirror("Dave") res6: String = DaveevaD 3">
Download presentation
Presentation is loading. Please wait.
Published byVeronica Horton Modified over 9 years ago
1
Functions and Methods
2
Definitions and types A function is a piece of code that takes arguments and returns a result A pure function is a function whose result depends only on its arguments You call a function If called again with the same arguments, a pure function will return the same result A method is a function that belongs to an object You “talk” to the object and ask it to run its method More formally, you send a message to the object 2
3
Syntax Method (in a class or object): def name (args ) = expression scala> class Person(name: String) { | def doubleName = name * 2 | } defined class Person scala> val jo = new Person("Jo") jo: Person = Person@1de9c46d scala> jo.doubleName res4: String = JoJo Function: (args ) => expression scala> val mirror = (name: String) => name + name.reverse mirror: String => String = scala> mirror("Dave") res6: String = DaveevaD 3
4
Operators and methods Reminder: Operators are really methods scala> 2 + 2 res0: Int = 4 scala> 2.+(2) res1: Int = 4 Binary (object + one argument) methods can be treated like operators scala> List(1, 2, 3, 4).contains(3) res2: Boolean = true scala> List(1, 2, 3, 4) contains 3 res3: Boolean = true 4
5
Function types Functions are objects, and every object has a type The type of (name: String) => name + name.reverse is String => String scala> (s: String, from: Int, to: Int) => s.drop(from).take(to - from + 1) res4: (String, Int, Int) => String = scala> res4("paper", 1, 3) res5: String = ape So the type of a function is ( types of its arguments ) => type of its result 5
6
Anonymous functions Functions can be given names scala> val foo = (n: Int) => n * (n - 1) foo: Int => Int = And then they can be called by name scala> foo(5) res1: Int = 20 But they don’t have to have a name to be called scala> ((n: Int) => n * (n - 1))(5) res2: Int = 20 6
7
Higher-order functions A higher-order function is one that either takes one or more functions as arguments, or returns a function as a result, or both Scala provides a number of higher-order functions, including the “big three”: map, filter, and reduce map applies a function to each element of a sequence, returning a sequence of the results filter applies a predicate (Boolean function) to each element of a sequence, and returns a sequence of those elements that satisfy the predicate (the predicate returns true ) reduce repeatedly applies a binary operation to pairs of elements of a sequence, returning a single value
8
map map applies a function to each element of a sequence, returning a sequence of the results scala> Array(1, 2, 3).map((x: Int) => x * x) res11: Array[Int] = Array(1, 4, 9) scala> Vector(1, 2, 3) map ((x: Int) => x * x) res12: scala.collection.immutable.Vector[Int] = Vector(1, 4, 9) scala> List(1, 2, 3) map ((x: Int) => x * x) res13: List[Int] = List(1, 4, 9) scala> Range(1, 6) map ((x: Int) => x * x) res15: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 9, 16, 25) scala> (1 until 6) map ((x: Int) => x * x) res16: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 9, 16, 25) scala> "boogie" map ((ch: Char) => "aeiou" contains ch) res17: scala.collection.immutable.IndexedSeq[Boolean] = Vector(false, true, true, false, true, true) 8
9
More about map scala> def addS(str: String) = str + "s" addS: (str: String)String scala> List("dog", "cat", "horse") map addS res0: List[String] = List(dogs, cats, horses) scala> List(1, 2, 3) map addS :9: error: type mismatch; found : String => String required: Int => ? List(1, 2, 3) map addS ^ scala> def addS(x: Any) = x + "s" addS: (x: Any)String scala> List(1, 2, 3) map addS res2: List[String] = List(1s, 2s, 3s) 9
10
filter filter applies a predicate (Boolean function) to each element of a sequence, and returns a sequence of those elements that satisfy the predicate (the predicate returns true ) scala> List(3, 1, 4, 1, 5, 9) filter ((x: Int) => x > 3) res0: List[Int] = List(4, 5, 9) scala> "University" filter ((ch: Char) => ch > 'm') res1: String = nvrsty scala> (2 to 20) filter ((x: Int) => isPrime(x)) res9: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 5, 7, 11, 13, 17, 19) scala> "Scala is a good language".split(" ") filter ((w: String) => w.length >= 5) res10: Array[String] = Array(Scala, language) 10
11
reduce reduce repeatedly applies a binary operation to pairs of elements of a sequence, returning a single value scala> (1 to 10) reduce ((x: Int, y: Int) => x + y) res12: Int = 55 scala> (1 to 10) reduce ((x: Int, y: Int) => x * y) res13: Int = 3628800 scala> List("one", "two", "three") reduce ((x: String, y: String) => x + y) res15: String = onetwothree Of course, many of these are already supplied by Scala scala> (1 to 10).sum res16: Int = 55 scala> (1 to 10).product res17: Int = 3628800 scala> List("one", "two", "three").mkString res21: String = onetwothree
12
Shortcuts When you define a method with def, you must specify the types of the parameter With literal functions, if the parameter type is obvious, you usually don’t need to specify it scala> List(3, 1, 4, 1, 5, 9) filter ((x) => x > 3) res0: List[Int] = List(4, 5, 9) With a single parameter and an inferred type, you can also leave out the parentheses scala> List(3, 1, 4, 1, 5, 9) filter (x => x > 3) res1: List[Int] = List(4, 5, 9) In fact, with a single parameter whose type is obvious, you can leave out the parameter name, and just use an underscore scala> List(3, 1, 4, 1, 5, 9) filter (_ > 3) res2: List[Int] = List(4, 5, 9) 12
13
Splitting lists scala> "one two three" takeWhile ((ch: Char) => ch != ' ') res0: String = one scala> "one two three" takeWhile (_ != ' ') res1: String = one scala> "one two three" dropWhile (_ != ' ') res2: String = " two three" scala> "one two three" span (_ != ' ') res3: (String, String) = (one," two three") scala> "one two three" partition (_ != ' ') res4: (String, String) = (onetwothree," ") scala> List(3, 5, 6, 8, 9) partition (_ % 2 == 0) res4: (List[Int], List[Int]) = (List(6, 8),List(3, 5, 9)) 13
14
Testing all elements sequence.forall( predicate ) checks if every element of the sequence satisfies the predicate scala> List(1, 2, 3) forall (_ > 0) res0: Boolean = true scala> List(1, -2, 3) forall (_ > 0) res1: Boolean = false sequence.exists( predicate ) checks if any element of the sequence satisfies the predicate scala> List(1, 2, 3) exists (_ < 0) res2: Boolean = false scala> List(1, -2, 3) exists (_ < 0) res3: Boolean = true 14
15
Extreme underscores If you have more than one parameter, you can sometimes use an underscore for each The first underscore stands for the first parameter, the second underscore for the second parameter, etc. scala> List(5, 3, 4, 2, 1) sortWith (_ < _) res1: List[Int] = List(1, 2, 3, 4, 5) scala> "This is a list of words".split(" ") sortWith (_.length < _.length) res2: Array[String] = Array(a, is, of, This, list, words) 15
16
find list.find( predicate ) returns, as Some( value ), the first value in the sequence that satisfies the predicate, or None if no such value is found scala> List(3, 1, 4, 1, 6) find (_ > 3) res5: Option[Int] = Some(4) scala> List(3, 1, 4, 1, 6) find (_ > 7) res6: Option[Int] = None scala> "Read the assignment carefully".split(" ") find (_.length > 6) res7: Option[String] = Some(assignment) I’ll review Option in just a moment 16
17
find with Strings scala> val digits = Math.PI.toString digits: String = 3.141592653589793 scala> List(3, 1, 4, 1, 6) find (_ > 3) res0: Option[Int] = Some(4) scala> digits find (_ > 3) res1: Option[Char] = Some(3) scala> digits find (_ > '3') res2: Option[Char] = Some(4) scala> 3 == '3' res3: Boolean = false scala> '3'.toInt res4: Int = 51 17
18
Working with an Option You can match on an Option val opt = men find (x => isHonest(x)) opt match { case Some(man) => println(s"$man is an honest man.") case None => println("Not found.") } An Option is a collection (of zero or one thing), so you can use collection operations on it scala> val abc = Some("abc") abc: Some[String] = Some(abc) scala> abc.isEmpty res5: Boolean = false scala> abc.isDefined res6: Boolean = true scala> for (a <- abc) println(a) abc scala> abc getOrElse("xyz") res8: String = abc 18
19
foreach Unlike the previously discussed higher-order functions, the return value of foreach is Unit, () foreach does something with each element of a sequence, and is used for its side effects scala> (1 to 10) foreach (x => print(x * x + " ")) 1 4 9 16 25 36 49 64 81 100 scala> var sum = 0; (1 to 10) foreach (x => sum += x * x) sum: Int = 385 Scala is “multi-paradigm”: It’s object-oriented and functional Functional languages don’t allow, or at least try to avoid, side effects The entire purpose of foreach is to have side effects! If you want to get side effects from a higher-order function, use foreach in preference to any of the others 19
20
for comprehensions A for comprehension is a convenient way to combine a number of map and filter operations scala> (1 to 20) filter (isPrime _) map (x => x * x) res1: scala.collection.immutable.IndexedSeq[Int] = Vector(4, 9, 25, 49, 121, 169, 289, 361) scala> for (i <- 1 to 20 if isPrime(i)) yield (i * i) res2: scala.collection.immutable.IndexedSeq[Int] = Vector(4, 9, 25, 49, 121, 169, 289, 361) 20
21
Why higher-order functions? Use of higher-order functions makes code shorter and (usually) easier to read With for comprension: scala> (1 to 10) map (x => x * x) res27: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) Just as a loop: scala> var v: Vector[Int] = Vector() v: Vector[Int] = Vector() scala> for (i v res29: Vector[Int] = Vector(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) Higher-order functions make certain tasks much easier Just like anything else, learning to use higher-order functions easily and effectively takes practice 21
22
The End 22
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.