
Learn to create and test type classes, build biotech to encode and decode types to and from an array of bytes, and apply functional techniques in Scala.
Configure a Scala project in IntelliJ IDEA Community Edition: import the build, organize source and test directories as roots, and use a Scala worksheet to run code.
Explore type classes in Scala Cats by building a channel to read and write objects, and compare simple, inheritance-based, and type-class approaches, with implicit helpers, laws, derivation, and syntax.
Examine designing a channel trait in Scala that writes a value of any type, compare a naive any-type method with alternatives, and discuss why this approach may be flawed.
Implement a file channel by overriding the right method, converting any object to bytes via pattern matching and ByteBuffer, and writing to a file with a Using block and flush.
Explore the trade-offs of a simple one write method interface, its type-handling risks, and the single-responsibility solution through a ByteEncodable with an encode method returning bytes.
This lecture extends the channel trait with a byte encodable full name case class and implements encode to produce a byte array, then writes it via a file channel.
Explore the channel typeclasses approach in functional programming with Scala Cats, comparing inheritance and typeclasses. Learn how encoders become typeclass instances, enabling safe testing and fast compile-time checks.
learn to implement a file channel with typeclass encoders in Scala Cats, writing bytes via a file output stream. build int and string encoders using getBytes and a right method.
Typeclasses enable a byte encoder for any type, including external ones, without altering the type's interface, and support multiple implementations for int, such as big endian and little endian.
Leverage implicits to supply type class pattern instances from implicit scope, avoiding explicit parameters, and add helper methods like apply (summoner) and instance to reduce boilerplate.
Learn how to use implicits with type classes in Scala Cats to provide a default main instance and override it with implicit instances, via companion object and implicit parameters.
Explore how implicits organize type class instances by using a companion object to provide default and in-scope instances for a custom switch type, showing encoding to bytes with implicit resolution.
Explore the summoner pattern in Scala, using implicitly to fetch a type class instance from implicit scope and the apply syntax to simplify calls, enabling flexible encoders.
Learn the instance method as a boilerplate reducer for type class instances. Convert objects to vals, generalize with a type A, and supply a function from A to bytes.
Introduce a second typeclass, the decoder, to read from the channel and decode bytes into an option of A, then implement color and string instances and decode the array.
In functional programming with scala cats, implement a companion object and apply to decode a byte array into an option of A using an implicit F and a decoder.
Explore the laws of type classes by building a byte codec with encode and decode, and validate isomorphism with discipline tests.
Build and verify a byte codec for int and string in Scala, encoding and decoding with a four byte buffer and length checks; apply discipline laws.
Leverage automatic instance derivation to create a byte encoder for option values from an encoder for the underlying type via a generic implicit def.
Explore how extension methods simulate type class syntax by enriching values with an implicit encoder, letting methods feel like they are part of the type while encoding integers.
Encode numbers and strings to bytes using implicit classes and extension methods, then decode them back while exploring a decoder exercise. Compare performance with value classes to avoid allocations.
Learn how typeclasses enable ad hoc polymorphism by extending types with implicit instances, providing multiple implementations, and validating laws with discipline and Scala test.
Explore well-known typeclasses from show and monoid to higher kinded types, then cover functor, applicative, monad, foldable, and traverse, and finally test their instances using the Catt library.
Explore the eq typeclass in Scala Cats and its laws—reflexivity, symmetry, antisymmetry, and transitivity—using a case class account and isEq to defer comparisons.
Learn how to implement equality for the account type using cats by creating implicit Eq instances, including by id and by number, with the summoner method and imports.
Learn how to order accounts using the cats order type class, with options by number, balance, or owner, and implement compare for type A under reflexivity, antisymmetry, transitivity, and totality.
Explore how to represent an account as a string by using the Cats show type class, compare it with the default toString, and consider representations like owner and balance.
Explore creating Show type class instances for an account in Scala Cats, including string-based shows by owner and balance, using implicit scope and syntax to summon instances.
Explore monoids by implementing a speed addition in meters per second using a combine operation and an empty element, ensuring associativity and left/right identities with a speed zero.
Create a monoid instance for speed in cats, implementing zero, combine, and add speeds; explore combine all, empty, and syntax shortcuts.
Define monoids for int sum, a mean monoid with an empty element that leaves the value unchanged, a list monoid with concatenation, and a string monoid with concatenation, noting associativity.
Explore higher kinded types and kinds, learn how type constructors like list, option, and map shape polymorphism, and examine database and applicative patterns in Scala Cats.
Wrap values in a secret class that hashes its toString to protect personal data. Use map to transform secrets and explore functor laws: identity and composition.
Develop a manually implemented Functor for option and list by coding map and applying a function to elements. Demonstrate the as operation to replace every element with a given value.
Define a validated trait with valid and invalid cases that accumulate errors. Use map2 to combine validators and apply the applicative typeclass with pure, app, and its laws.
Explore implementing an applicative for Validated in cats, lifting values with pure, applying functions in context, and accumulating errors across multiple values; learn patterns with map, map2, and currying.
Examine optionality with a custom option type, returning some or none in lookups, and streamline with flatMap and for comprehension to illustrate monad laws in Cats.
Learn how to implement a monad for option in Scala Cats by defining pure, flatMap, map, and flatten, and use for-comprehensions to compose option-valued computations.
Explore the list monad by using for expressions and flatMap to generate all sums from two lists, then implement a custom flatMap with pure, recursion, and concatenation.
Explore the either monad in scala cats, focusing on right-biased error handling, fixing the left or right type parameter, and implementing a monad instance with smart constructors.
Explore the try monad and its error handling semantics, comparing it to either with success and failure, implementing pure and flatMap, and examining how exceptions can break monad laws.
Explore how monad error encodes failure using option, either, and try, with an http client example, contrasting exception throwing with type-safe error handling in Scala Cats.
This lecture explores implementing monad error instances for option, either, and try, using unit, left, and throwable as error markers. It demonstrates recoveries and error handling in http request simulations.
The lecture demonstrates generalizing an execute request method across monads using higher-kinded types, MonadError, and pure/raise methods, enabling handling of errors for option, try, and either.
Explore how the attempt method converts monad values into an either, yielding right for success and left for failure, using option and try and illustrating ensure with a predicate.
Implement foldable operations by folding a custom list with fold right, deriving sum, length, and filter positive through recursive patterns on nil, head, and tail.
Explore foldleft in functional programming with scala cats, using a tail-recursive accumulator to fold a list from the left and understand associativity.
Refine a foldable list by implementing a robust apply method and smart constructors. Demonstrate foldLeft and foldRight, laziness, and foldMap with monoids, plus sum, length, and filter tests.
Implement the find function for a foldable using foldLeft or foldRight and a predicate. Return an option, handling head and tail cases with none or some.
Explore the exists function for foldable structures by implementing a boolean predicate search using find and a full left fold, handling empty and non-empty lists.
Discover how any foldable can be represented as a list and implement a list builder using nil, head, tail, and recursive calls, correcting order with fold right.
Traverse lists with a find people by names example returning an option of people, then generalize to any applicative using Cats traversable. Explore traverse laws like identity and sequential composition.
Examine traverse and sequence in Scala Cats, implementing a list functor, mapping over a list, and swapping inner and outer types via sequence, with option and list examples.
Implement the traverse instance for option, pattern matching none and some, lift to the applicative with pure, map, and some, and demonstrate traverse with list as applicative.
Learn to test type class instances from Cats and property tests for your classes, implement eq for box and a monad instance with map and tail-recursive logic.
Learn to test type class instances with discipline, using generators and arbitraries to verify box and monad laws in Scala Cats.
Test properties by wrapping a value in a box and unwrapping it to recover the original value. Use property checks with arbitrary generators and provide explicit generators when needed.
Revisit the well-known type classes in Scala Cats, map the hierarchy from monoid to eq, and show how monad, applicative, and functor enable sequencing, error handling, and traverse.
Learn techniques with cats: validated type, reader for dependency injection, writer Mona for tracking, eval monad for laziness, state monad for tic tac toe, monad transformers to suspend side effects.
Explore building and composing validated values with cats, using non-empty list and non-empty chain to accumulate errors, and convert between validated and either representations.
Explore dependency injection via functions by wiring a db client into the account service to find by id, save, and update, then simplify composition with the reader monad.
Learn to implement the reader monad in Cats by building sign and parity readers, running them with an int environment, and composing them via flatMap and for expressions.
Learn to inject dependencies using an environment that provides account and person repositories, read them via a Reader, and compose modules with traits and the with operator to manage dependencies.
Work through a multi-step exercise showing module organization and dependency injection with the reader monad to wire an account repository, a person repository, and an email service for account notifications.
Apply and track shopping cart discounts using functional programming: implement client and item discounts, use mapN to combine discounts, and log the discount history with the writer monad.
Explore the writer monad in Scala Cats, building writers with logs and values, resetting logs, and composing with map, flatMap, and mapN to accumulate results.
Demonstrates using the writer monad to compute shopping-cart discounts, totals, and log output, applying applicative, monoid, foldMap, and traverse to sum discounts.
Learn to build a shopping cart via a macro that logs each creation step from client to product to cart items using writer, for expressions, and traverse in Scala Cats.
Explore state management in functional Scala Cats by modeling a tic tac toe board and turn as immutable state, using switch turn and play, and the state monad.
Explore the state monad in Scala Cats, including creating state, running it, and using get, set, modify, inspect, plus map, flatMap, and applicative composition.
Learn state management in a functional Scala Cats setting by building a tic tac toe game that tracks turns, checks for winners, prints the board, and implements replay.
Explore stack safety in the JVM with trampolines in functional programming to convert recursive calls into safe heap-based evaluation, with thunks, done and enabling tail call optimization and mutual recursion.
Explore tail recursion and trampolines in Scala to fix stack overflow in factorial and mutually recursive isEven/odd, using an accumulator and a run method to evaluate trampolines.
Learn to implement a stack-safe flatMap for a trampoline, using resume, associativity of map, and a monadic run to model computations as data.
Learn how to implement infinite streams in Scala with lazy evaluation and a trampoline-based approach to avoid stack overflow, and compare eager, later, always, and deferred evaluation modes.
Explore the eval monad in Scala Cats, comparing eager, defer, and always evaluation, and learn to compose with map and flatMap for stack-safe computation using deferral and trampoline.
Explore evaluation modes for streams in Scala Cats by implementing a lazy, stack-safe infinite stream with the Eval monad, including take and map.
Explore tailRecM and safe recursion for monads, and see how iterateWhile for the option monad uses left and right to avoid stack overflow.
Explore reading a method signature and adding error handling and dependencies with the reader monad. Show how monad transformers combine reader and either to simplify deposit money logic.
Explore how to create and manipulate readerT with cats, lifting errors and values into Kleisli, using mapF to switch from either to option, and applying pure, map, and flatMap.
Explore composing monad transformers in Scala Cats by implementing OptionT to stack option and error effects, and learn flatMap variants, benefits, and performance caveats.
in this section on suspending side effects, the lecture shows how substituting expressions preserves referential transparency without side effects; printing to the console breaks this, causing duplicate or out-of-order logs.
Explore suspending side effects with an IO data type in scala cats, describing computations separately from execution, and running them later to preserve referential transparency.
Explore implementing a monad for io with pure and flatMap, suspending side effects, and composing computations that only perform effects when run.
Explore validated monad error accumulation, applicative composition, and reader, writer, and state monads; implement tic tac toe, lazy eval, and suspend side effects to preserve referential transparency.
Showcase a command line expense tracker for a group, using scala cats, showing adding people, recording expenses, computing debts, and input validation with a 32-character name limit and letters-only rule.
Dissect the project's architecture by outlining package structure, models (money, person, expenses), services, and a layered IO and monad-transformer stack using reader, state, and either to manage effects and errors.
Explore validations in Scala Cats by implementing string length checks and converting strings to doubles with Validated from option, guided by test-driven development.
Learn to build generators for person and expense in Scala Cats using arbitrary, gen, and for yield, generating names of length 1–30 and a non empty set of people.
In this lecture, learn to create a validated person instance in Scala Cats by enforcing non-empty name, letter-only characters, and a max length of 32, while accumulating errors.
Implement and test a money class in scala cats: add an implicit order, support safe division by integers returning none for zero, and create validated money with non-negative amounts.
Implement the expense model in Scala Cats with a show instance and tests, plus validations. Divide the amount among payer and participants and format the result as a readable string.
Understand debt by payee, a map from person to money, and implement operations like debt lookup, combining maps, and a monoid-based money sum for multiple participants.
Model debts with a map from recipient to a map of payers and amounts, using functional style in Scala Cats, with examples and tests.
Implement the person service with a name-to-person map stored in state, providing find by name, add person, and get all people, using state inspect and state modify.
Implement a live expense service that adds expenses to state and computes debt by payer by mapping expenses to debt by payer, combining with a monoid, and simplifying redundant entries.
Demonstrate how the new IO supports race error and error handlers, updating the run and resume methods to register and apply error handlers and continue computations.
Learn how to wrap values into an app using reader, state, and either layers. See how to lift and transform state with a state transformer to manage environment and errors.
Read participant names from the console until the user types end, building the list with a for-comprehension and left-right recursion, then return the final participant list.
Apply data validations to a simple dataset, ensure the amount is a money double returned as a double, and traverse participants to assemble payer, amount, and participants into validated data.
Implement a findPerson command in Scala Cats that returns a person by name, converting a none into the provided error message using the environment and from option to error.
Implement the addPerson command by reading the environment and person data (the name), creating the person, updating the state via the personal service, and returning a success message.
Implement an app command executor with recovery that prints errors to the console and continues execution. The main loop stops when the command signals exit, otherwise it keeps looping.
When we start our journey as a Scala developer, our first impression of the language may be that of 'a better Java'. We learn about classes, traits, pattern matching and some other constructs that make our life easier. At some point we come across the amazing higher-order methods such as map, filter and fold. These serve as a great first taste of functional programming.
But what if I told you that there is much more than that? In this course I will show you how standard functional programming practices can help you write code that is more generic, robust and testable.
This course is divided into 3 main sections.
In the first section, we will learn about typeclasses. We will use as a driving example the problem of encoding and decoding objects into and from bytes. By the end of this section you will be able to create your own typeclasses and use the typeclass pattern to write polymorphic code.
In the second section, we will take a look at some of the most common typeclasses in functional programming, including Monads, Applicatives, Functors and many more. We will use the famous Cats library to provide us with their implementations, and we will use Discipline along with ScalaCheck and ScalaTest to test their laws. By the end of this section, you will be able to write lawful instances of these typeclasses for any of your types, and test their validity in an automated manner.
In the third and final section, we will learn to perform many common programming tasks with functional structures. These tasks include:
- Validations via the Validated datatype
- Dependency injection with the Reader monad
- Tracking data in our computations with the Writer monad
- Managing state with the State monad
- Writing stack safe computations with Trampolines
- Making computations lazy with the Eval monad
- Composing monad stacks via monad transformers such as ReaderT and OptionT
- Suspending effects with a simple but useful implementation of the IO monad
I'm a big believer of learning by doing so I've included a lot of in-video exercises, along with quizzes and assignments at the end of each section. I hope you enjoy doing them as much as I enjoyed putting them together!
Without further ado, I want to give you a big welcome to the course and the thrilling world of functional programming!