map
function:
val triple = (x : Int) => 3 * x (1 to 10).map(triple) // yields 3 6 9 12 ... 30
Int
List[Int]
, function (Int) => Int
, returns List[Int]
def map(lst : List[Int], fun: (Int) => Int) : List[Int] =
Nil
, otherwise apply fun
to lst.head
and use recursion:
if (lst.isEmpty) Nil else fun(lst.head) :: map(lst.tail, fun)
map(List(1, 2, 3), (x : Int) => 3 * x)
What should
map
do with each element inlst
?
val n = 3 val fun = (x : Int) => n * x // What is fun(2)?
n
is not defined in the scope of fun
, but that is ok. In the body of a function, you can use any variable from the enclosing scope.n
is immutable, so it will always be 3. But consider this:
def multiplyBy(n : Int) = (x : Int) => n * x
val quadruple = multiplyBy(4) // the function (x : Int) => 4 * x
quadruple(5) // yields 20
multiplyBy
yields a different function.n
def twice(f: (Int) => Int, x : Int) = f(f(x)) twice((x) => 42 * x, 3) // Ok, x : Int is inferred from context
List(1, 2, 3).map((x) => x * x)
List[A].map(f : (A) => B) : List[B]
A
is Int
since List(1, 2, 3)
is a List[Int]
f
must be (Int)=> . . .
x
must be Int
()
around a single inferred parameter
List(1, 2, 3).map(x => x * 0.5)
List(1, 2, 3).sortWith((x, y) => x > y)
// need ()
with 2 or more parameters, or with 0 parameters
_
for a parameter that only occurs once in the body
List(1, 2, 3).map(_ * 0.5) List(1, 2, 3).sortWith(_ > _)
_
can't be in an expression that is passed to another function.
List(1, 2, 3).map(math.sqrt(_ + 1)) // Error—Can't pass_ + 1
tomath.sqrt
List(1, 2, 3).map(math.sqrt(_) + 1) // Ok
map
produces a list of values.def sum(List[Int] lst): Int
def reduce(lst: List[Int], op: (Int, Int) => Int): Int
val result = reduce(lst, (x, y) => x + y)
val result = reduce(lst, _ + _)
def reduce(lst: List[Int], op: (Int, Int) => Int): Int = if (lst.tail.isEmpty) lst.head else op(lst.head, reduce(lst.tail, op))
lab3/report.txt
inside the Git repo. Include the coder's name in the report! val isEven = (x : Int) => x % 2 == 0
(1 to 10).filter(isEven)
. As always, don't type the period, but type ENTER. What do you get? filter
does.val gen = new scala.util.Random gen.nextInt(10) gen.nextInt(10)
randList(len : Int, n : Int) : List[Int]
that makes a list of length len
of random integers between 0 and n
- 1. For example, randList(5, 10)
might yield a list of numbers 5 1 2 0 9. Define randList
as a recursive function. What is the code of your function?
Hint: If len
is 0, the result is nil
. Otherwise, it is gen.nextInt(n) ::
something. What is your definition?
Note: You need not define gen
. You already defined it in part 1. Just use it.
randList(5, 1000)
? For randList(1000, 5)
?randList
a closure? greaterThan100(lst : List[Int])
that returns only those integers in lst
that are greater than 100. Don't use recursion; simply call filter
with an appropriate function:
def greaterThan100(lst : List[Int]) = { val fun = ... // your work lst.filter(fun) // NOTE: The last expression in a { ... } is its value }
What is your function's code?
greaterThan100(randList(10, 200))
? Why does that give you confidence that you implemented everything correctly? def greaterThan(n : Int, lst : List[Int]) = { val fun = ... // your work lst.filter(fun) }
For example, greaterThan(50, nums)
yields all values of nums
> 50.
What is the code of your greaterThan
function?
greaterThan(100, randList(10, 200))
? fun
inside greaterThan
a closure?reduce(List(1,2,3,4,5), (x, y) => x - y)
?reduce
called reduceLeft
and reduceRight
. Try
(1 to 5).reduceLeft(_ - _) (1 to 5).reduceRight(_ - _)What do each of them do?
reduce
to compute the decimal value. For example, List(1, 7, 2, 9)
should turn into 1729. Hint: (x, y) => 10 * x + y
.reduce
in the lecture. Which one? Implement the other. Here is an outline:
def otherReduce(lst: List[Int], op: (Int, Int) => Int) = { def otherReduceHelper(lst: List[Int], op: (Int, Int) => Int, partialResult: Int): Int = if (lst.isEmpty) ... else otherReduceHelper(..., op, op(..., ...)) otherReduceHelper(..., op, ...) }