**Scala tutorials**

**Functional Design Principles In Scala: Functors, Monad and Monoids**

ScalaÂ is a functional programming language and each functional programming language should follow functional design principles. In this article we will briefly see a few key design principles and their examples.

**Functors In Scala**

Functor is a FP principal maps two different data types(categories). Scala has functor type implementations but actual functor implementations can be found in libraries like cats etc.

**Below are some features of Functor-**

Â – It provides facility to wrap and unwrap things(categories)

Â – It provides two functionalities, one to do mapping and another wrapping.

Â – It follows identify and associativity rules.

Â – It has a map() function and a unit() functionÂ (can be named anything inside)

Â – Is all about applying functionalities on data inside a CONTEXT which are allowed by context.

Â – It is a type class.

Â – it defines how a map will be applied to data.

**Syntax:**

map :(A=>B) => F[A]=>F[B]

**Example of Functor:**

object FunctorsExample { case class MyContainer[A](things: A) { def map[B](fn: (A) => B): MyContainer[B] = { //Custom Functor MyContainer(fn(things)) } } val doubleThings = (data: Int) =>data*2 def main(args: Array[String]): Unit = { val mythings = MyContainer(100) val result = mythings.map(data => doubleThings(data)) println(result) } }

**Output**

MyContainer(200)

**Monad In Scala**

Monad is FP principal in Scala, it is used to provide mapping between twoÂ types(categories).

**Key points to be noted for Monad**

Â Â Â Â Â Â Â Â – Monad is a FP principle which is used for mapping between two types/categories.

Â Â Â Â Â Â Â Â – It is used to create structure to hold things inside and facilitate them.

Â Â Â Â Â Â Â Â – It is a type class

Â Â Â Â Â Â Â Â – On top of the functor it has flatMap() and flatten() functions.

Scala List or Maps donâ€™t have any specific monad implementations but they have feature line monad, map, flatMap() and flatten(), so we can say they somewhat follow Monad FP.

**Example Of Monad**

See in below example Monad has map() like Functor but also has flatten and flatMap() to take out things if they are wrapped twice.

object MonadExamples { def main(args: Array[String]): Unit = { //Custom Monads case class MyContainer[A](things: A) { def map[B](fn: (A) => B): MyContainer[B] = MyContainer(fn(things)) def flatten = things def flatMap[B](fn: (A) => MyContainer[B]): MyContainer[B] = fn(things) } //Using Monads val mythings = MyContainer(100) //In this case by using map we can unwrap, transform things, but things of Monad are still in wrap so we use flatten() and flatMap() to take them out. val tripleThings = (data: Int) => MyContainer(data * 3) //So here we wont get container of container as flatten will flat it println(mythings.map(tripleThings).flatten) println(mythings.flatMap(tripleThings)) } }

**Output**

MyContainer(MyContainer(300))

MyContainer(300)

MyContainer(300)

**Monoids In Scala**

Monoids are another FP design principle to implement your data types of Monoid. Monoid provides a feature to do binary operation on two inputs and also defines identity/empty/zero element method.

**Features and important points related to Monoids**

Â -Monaid is type together with associativity binary (op) which has an identity element(0),

Â Â – Monoid is a small FP data structure.

Â Â – Monoid is a type class.

Â Â – It is used to perform algebraic calculations on individual elements

Â Â – It is a ADT (algebraic data type)

Â Â – It also belongs to category theoryÂ with one single object in category

Â Â – It is used to build complex systems/computations by combining small operations.

Â Â – They allow to perform single binary operation

In below example we can see so many Monoids implemented and used:

**Example:**

object MonoidsExample { //Monoid data structure or type class trait Monoid[T] { //should have identity rule and identity element def empty : T // name can be identity, empty, zero element def combine(arg1: T, arg2: T): T // can be add, op, combine etc. } //Example Int addition monoid val indAdditionMonoid = new Monoid[Int] { override def empty: Int = 0 override def combine(arg1: Int, arg2: Int): Int = arg1+arg2 } implicit val indAdditionMonoid1 = new Monoid[Int] { override def empty: Int = 0 override def combine(arg1: Int, arg2: Int): Int = arg1+arg2 } val intMethodMonoid = new Monoid[Int=>Int] { override def empty : Int=>Int = (arg:Int) => arg override def combine(arg1: Int=>Int, arg2: Int=>Int) = arg1 andThen arg2 } def combineAll(listInt : List[Int]) (monoid: Monoid[Int] ): Int = { listInt.fold(monoid.empty)((accumalator, data) => monoid.combine(accumalator,data)) } def main(args: Array[String]): Unit = { println(indAdditionMonoid.empty) println(indAdditionMonoid.combine(3,4)) println(intMethodMonoid.combine((data:Int) => data*2, (data:Int) => data*3)) println(combineAll(List(1,2,3))(indAdditionMonoid)) } }

**Output**

0

7

scala.Function1$$Lambda$7/901506536@2c8d66b2

6

Â There are other design principles as well but above mentioned are the most used ones in any FP language.

**Â Reference**

**Â Next Article**

- Scala Interview Questions