ScalaFP: Let’s Start with Type Class

Reading Time: 2 minutes

Before we start talking about the Functional Programming with the Scala Cats, we should refresh our memory about the Type Class and Implicit. These are the base when we start learning the Scala Cats.

Let’s start the discussion with the Type Class.

Type Class

A type class is an interface or API that represents some functionality, which we want to implement. Type class is programming pattern in Haskell which allows us to extend existing libraries with new functionality. In Cats, a type class is represented by a trait with at least one type parameter.(If you don’t know about the trait or want to refresh look here: Back2Basics: The Story of Trait – Part 1)

Now we will see, how can we implement Type Class with traits:

sealed trait Json
final case class JsObject(get: Map[String, Json]) extends Json
final case class JsString(get: String) extends Json
final case class JsNumber(get: Double) extends Json
case object JsNull extends Json
trait JsonWriter[A] {
def write(value: A): Json
}

view raw
JsonWriter.scala
hosted with ❤ by GitHub

Here as we can see that JsonWriter is a Type class with the Json which provides the support for the rest operations.

Now we will discuss the Type Class Instances because it provides the implementation for the types.  Now in Scala, we create the instance with the help of concrete implementation and implicit. Example:

final case class Person(name: String, email: String)
object JsonWriterInstances {
implicit val stringWriter: JsonWriter[String] =
new JsonWriter[String] {
def write(value: String): Json = JsString(value)
}
implicit val personWriter: JsonWriter[Person] =
new JsonWriter[Person] {
def write(value: Person): Json =
JsObject(Map(
"name" > JsString(value.name),
"email" > JsString(value.email)
))
}
}

Now we will create a Type Class Interface, which will expose the functionality to the users. Interface use the generic method that will take the instance of the type class as an implicit parameter. We can access interface in two way:

  1. Interface Object
  2. Interface Syntax

Interface Object: Now we can create an interface. It will place a method into a singleton object:

object Json {
def toJson[A](value: A)(implicit w: JsonWriter[A]): Json = w.write(value)
}

view raw
Json.scala
hosted with ❤ by GitHub

Now we can call it like this:

import JsonWriterInstances._
Json.toJson(Person("Dave", "dave@example.com"))
//res1: Json = JsObject(Map(name -> JsString(Dave), email -> JsString(dave@example.com)))

view raw
Example.scala
hosted with ❤ by GitHub

Here we can see that we haven’t provided the implicit parameter but we are calling the toJson method. Now compiler will search for the type class instance and provide it to the call like:

Interface Syntax: We can use extension methods also for extending the existing type with the interface.

object JsonSyntax {
implicit class JsonWriterOps[A](value: A) {
def toJson(implicit w: JsonWriter[A]): Json =
w.write(value)
}
}

view raw
JsonSyntax.scala
hosted with ❤ by GitHub

Now we can use it, like this:

import JsonWriterInstances._
import JsonSyntax._
Person("Dave", "dave@example.com").toJson
// res6: Json = JsObject(Map(name -> JsString(Dave), email -> JsString(dave@example.com)))

Again we can see that we haven’t provided the implicit parameter but we are calling the toJson method. Now compiler will search for the type class instance and provide it to the call like:

So we have discussed till now for the Type Class. In our next blog, we will talk about the Implicit and Scala Cat Structure.

Reference:

Scala with Cats


knoldus-advt-sticker


 

Written by 

Anurag is the Sr. Software Consultant @ Knoldus Software LLP. In his 3 years of experience, he has become the developer with proven experience in architecting and developing web applications.

5 thoughts on “ScalaFP: Let’s Start with Type Class2 min read

Comments are closed.

%d bloggers like this: