# 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.