Top Functional Programming (Cats & Scalaz) Interview Questions and Answers in Scala (2025)
Top Functional Programming (Cats & Scalaz) Interview Questions and Answers in Scala (2025)
1. What is a Typeclass in Functional Programming (Cats/Scalaz)?
Answer:
A typeclass is a pattern that defines behavior for types
without modifying them. It uses parametric polymorphism and implicit
resolution.
In Cats:
import cats.Showimport cats.implicits._ case class User(name: String) implicit val userShow: Show[User] = Show.show(_.name)println(User("Alice").show)
Key concepts: Extensibility without inheritance, separation of behavior from data.
2. What is a Functor and how is it used in Cats?
Answer:
A Functor is a typeclass that provides a map function to transform the value
inside a context.
import cats.Functorimport cats.implicits._ val list = List(1, 2, 3)val result = Functor[List].map(list)(_ + 1) // List(2, 3, 4)
Functors enable structure-preserving transformations.
3. What is a Monad and how does it differ from a Functor?
Answer:
A Monad extends a Functor by adding flatMap (also called bind), enabling sequential
computations.
import cats.Monad val optMonad = Monad[Option]optMonad.flatMap(Some(2))(x => Some(x * 3)) // Some(6)
Difference: All Monads are Functors, but not all Functors are Monads.
4. Explain Applicative
vs Monad in
Cats.
Answer:
· Applicative: Allows applying functions independently within contexts.
· Monad: Supports dependent sequencing of operations.
import cats.ApplicativeApplicative[Option].map2(Some(1), Some(2))(_ + _) // Some(3)
Applicative is more parallelizable, Monad is more expressive.
5. What is the difference between Either and Validated in Cats?
Answer:
·
Either:
short-circuits on first error
·
Validated:
accumulates multiple errors (great for validation)
import cats.data.Validatedimport cats.implicits._ val res = ("Error1".invalidNel[String], "Error2".invalidNel[String]).mapN(_ + _)// res: Invalid(NonEmptyList(Error1, Error2))
Use Validated for form
validations, and Either
for fail-fast workflows.
6. How do you handle effect types using Cats Effect (IO Monad)?
Answer:
IO encapsulates side
effects and ensures they are executed in a controlled manner.
import cats.effect.IO val sayHello: IO[Unit] = IO(println("Hello"))val program = for { _ <- IO(println("Start")) _ <- sayHello} yield ()
Benefits: Referential transparency, composability, async execution.
7. What is the Semigroup
and Monoid
in Cats?
Answer:
· Semigroup: Combines two values of the same type.
·
Monoid: Adds an identity
element (empty).
import cats.Monoidimport cats.implicits._ Monoid[Int].combine(1, 2) // 3Monoid[String].empty // ""
Used in reductions, logging, data aggregation.
8. How does Scalaz differ from Cats?
Answer:
|
Feature |
Cats |
Scalaz |
|
Style |
Modular, community-focused |
More academic, abstract |
|
Ecosystem |
Actively maintained |
Slower development |
|
Design |
Typeclasses only |
Typeclasses + data structures |
Cats is preferred in modern Scala, while Scalaz is more hardcore FP.
9. How do you accumulate errors in Cats using ValidatedNel?
Answer:
Use ValidatedNel to collect
multiple errors:
import cats.data.ValidatedNelimport cats.implicits._ val res1: ValidatedNel[String, Int] = "Invalid age".invalidNelval res2: ValidatedNel[String, Int] = "Invalid name".invalidNelval combined = (res1, res2).mapN(_ + _) // Invalid(NonEmptyList(Invalid age, Invalid name))
Perfect for form validation, data pipelines, or ETL jobs.
10. What is Kleisli
in Cats and where is it used?
Answer:
Kleisli[F[_], A, B] wraps a
function A => F[B],
making it composable for effectful functions.
import cats.data.Kleisliimport cats.effect.IO val toUpper: Kleisli[IO, String, String] = Kleisli(s => IO(s.toUpperCase))toUpper.run("hello").unsafeRunSync() // "HELLO"
Used in dependency injection, microservices, or monadic pipelines.
%20Interview%20Questions.jpeg)