Functions Intro

FILE : Functions1Demo

Functions as a type

When we declare simple variable we can think of it as a variable of type :Int,Double,Data,User etc

val someValue:Int=5

Functions declarations are very similar , we also give them name and type

val incrementFunction3:Int => Int = v1 => v1 + 1

The type Int => Int is a type _of function which is a form of operation "transform int into int"_

Also scala show use how important is syntatic help when defining function because without _sugar _it would look like this

val incrementFunction:Function[Int,Int] = new Function[Int,Int](){
      override def apply(v1: Int): Int = v1+1
}

Functions Composition

To compose two functions A=>B and C=>D the only condition is to B and C be the same so we can compose User=>String _and _String=>Int _but you can not compose Company=>List[Users] with String=>Int_

val f1:Int=>Int =  i=> i+1
val f2=(i:Int) => i*10

val f1AndThenf2= f1 andThen f2
val f1Composef2 = f1 compose f2

Functions and Methods

Method can be converted into function - it is called ETA Expansion . It happens automatically when we pass method when similar function is expected.

We can also convert method to function on our own when we add underscore after method name and assign it to variable.

def method(i:Int):Int = i + 1

val asFunction: (Int) => Int =  method _

Because methods can have generics so they are more elastic than functions but to have composition you need to convert them to functions.

Partial Functions

Partial Function is a function which doesn't have result defined for each input. The simplest example will be _divide _which is not defined for input 0.

val divide:(Double,Double) => Double = {
      case (a,b) if b!=0 => a/b
}

partial function are useful because very often you can perform partial pattern matching on you domain classes. So for example you can have a function defined only for specific type of customers.

To not left unhandled inputs which may lead to bugs you can join partial functions so they create total function.

val zeroHandler:PartialFunction[(Double,Double), Double] = {
      case (_,0) => Double.PositiveInfinity
}

//EXPLAIN WHY TOTAL FUNCTIONS ARE IMPORTANT
val totalFunction = dividePartial orElse zeroHandler

Exercises

FILE : Functions1Exercises

Exercise 1

  • simple function definition and composition with andThen - just follow the types

Exercise 2

  • You can find incomplete methods at the bottom of the file
object OnlyMethods{
  def trim(s:String): String = ???
  def removeDots(s:String): String = ???
  def toUpper(s:String): String = ???
}

Complete them so that functions created from methods in exercise 2 will past test

Exercise 3

In this exercise you will work with partial functions. Because partial functions are not defined for all inputs then you have to create two of them : primary for main use case and second for not handled inputs

//extract email if price is larger than 50
val bigPurchases:PartialFunction[Purchase,Email] = ???

  //this is default handler which should return DEV_NULL_EMAIL
val defaultHandler:PartialFunction[Purchase,Email] = ???

Check the test to find out how they are used.

results matching ""

    No results matching ""