### Preview Documentation Site Source: https://github.com/typelevel/cats/blob/main/CONTRIBUTING.md Run this command in the sbt console to start a local preview server for the documentation site. ```shell docs/tlSitePreview ``` -------------------------------- ### CombineAllOption Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/monoid.md Demonstrates combining a list of NonEmptyList instances by lifting them into Option and using the Option Monoid. ```scala import cats.Monoid import cats.data.NonEmptyList import cats.syntax.all._ val list = List(NonEmptyList(1, List(2, 3)), NonEmptyList(4, List(5, 6))) val lifted = list.map(nel => Option(nel)) Monoid.combineAll(lifted) ``` -------------------------------- ### Basic Reducible Reduce Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Demonstrates the basic 'reduce' method on a NonEmptyList of strings. ```scala Reducible[NonEmptyList].reduce(NonEmptyList.of("a", "b", "c")) ``` -------------------------------- ### Reducible ReduceMap Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Shows how to use 'reduceMap' to transform elements before reducing them in a NonEmptyList. ```scala Reducible[NonEmptyList].reduceMap(NonEmptyList.of(1, 2, 4))(_.toString) ``` -------------------------------- ### Enter Nix Development Environment Source: https://github.com/typelevel/cats/blob/main/CONTRIBUTING.md This command starts a Nix shell with all necessary dependencies for Cats development. The first run may take time to download dependencies. ```shell nix-shell --pure ``` -------------------------------- ### Process Bookings Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/statet.md Demonstrates processing a list of bookings and attempting to process a list with a duplicate reservation, showing the outcome of the reservation system. ```scala val bookings = NonEmptyList.of( TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 1, hour = LocalTime.parse("10:00:00")), name = "Gandalf" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 2, hour = LocalTime.parse("10:00:00")), name = "Legolas" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 1, hour = LocalTime.parse("12:00:00")), name = "Frodo" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 2, hour = LocalTime.parse("12:00:00")), name = "Bilbo" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 3, hour = LocalTime.parse("13:00:00")), name = "Elrond" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 1, hour = LocalTime.parse("16:00:00")), name = "Sauron" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 2, hour = LocalTime.parse("16:00:00")), name = "Aragorn" ), TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 2, hour = LocalTime.parse("18:00:00")), name = "Gollum" ) ) TableReservationSystem.processBookings(bookings) TableReservationSystem.processBookings( bookings :+ TableReservationSystem.Reservation( TableReservationSystem .ReservationId(tableNumber = 1, hour = LocalTime.parse("16:00:00")), name = "Saruman" ) ) ``` -------------------------------- ### Function Composition Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/kleisli.md Shows the result of composing two simple functions using `andThen`. ```scala twiceAsManyCats(1) // "2 cats" ``` -------------------------------- ### Reducible ReduceLeftTo Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Illustrates 'reduceLeftTo' which combines mapping and left-associative reduction on a NonEmptyList. ```scala Reducible[NonEmptyList].reduceLeftTo(NonEmptyList.of(1,2,3,4))(_.toString)((s,i) => s + i) ``` -------------------------------- ### Subtyping-based combineAll (Illustrative) Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses.md An illustrative example showing a subtyping approach to combineAll, highlighting potential issues with empty lists. ```Scala // Subtyping def combineAll[A <: Monoid[A]](list: List[A]): A = ??? ``` -------------------------------- ### Ordering for Int comparison Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/contravariant.md Shows basic usage of scala.math.Ordering for comparing integers. This is a foundational example for understanding ordering operations. ```Scala Ordering.Int.compare(2, 1) Ordering.Int.compare(1, 2) ``` -------------------------------- ### Asynchronous IorT Program Execution Examples Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/iort.md Shows the results of executing the asynchronous addressProgramAsync, demonstrating how to await results from Future[Ior[Logs, *]]. ```scala import scala.concurrent.Await import scala.concurrent.duration._ Await.result(addressProgramAsync("7", "Buckingham Palace Rd"), 1.second) Await.result(addressProgramAsync("SW1W", "Buckingham Palace Rd"), 1.second) Await.result(addressProgramAsync("SW1W", ""), 1.second) ``` -------------------------------- ### Verify CsvCodec Law with Foo Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/invariantmonoidal.md Demonstrates the CsvCodec law by writing a Foo instance to CSV and then reading it back, asserting that the result matches the original. ```scala val foo = Foo("foo", BinDec(10, 10), BinDec(20, 20)) val fooCsv = fooCodec.write(foo) fooCodec.read(fooCsv) fooCodec.read(fooCodec.write(foo)) == ((Some(foo), List())) ``` -------------------------------- ### Initiate Release Process Source: https://github.com/typelevel/cats/blob/main/PROCESS.md Execute the 'release' command to start the automated release procedure. This command performs validations, signs artifacts with GPG, and publishes them to Sonatype. ```shell release ``` -------------------------------- ### Int Semigroup Example with Addition Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/semigroup.md Demonstrates the Semigroup instance for Int using the addition operator. Shows explicit combine calls and infix syntax. ```Scala import cats.Semigroup implicit val intAdditionSemigroup: Semigroup[Int] = _ + _ val x = 1 val y = 2 val z = 3 ``` ```Scala Semigroup[Int].combine(x, y) Semigroup[Int].combine(x, Semigroup[Int].combine(y, z)) Semigroup[Int].combine(Semigroup[Int].combine(x, y), z) ``` ```Scala import cats.syntax.all._ 1 |+| 2 ``` -------------------------------- ### combineAll Examples Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/monoid.md Demonstrates the use of the generic combineAll function with different types: Int, String, Map, and Set. ```scala import cats.syntax.all._ combineAll(List(1, 2, 3)) combineAll(List("hello", " ", "world")) combineAll(List(Map('a' -> 1), Map('a' -> 2, 'b' -> 3), Map('b' -> 4, 'c' -> 5))) combineAll(List(Set(1, 2), Set(2, 3, 4, 5))) ``` -------------------------------- ### Monoid Combine Examples for Int Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/monoid.md Demonstrates combining an Int with the empty value using the Monoid instance. ```scala Monoid[Int].combine(x, Monoid[Int].empty) Monoid[Int].combine(Monoid[Int].empty, x) ``` -------------------------------- ### Synchronous IorT Program Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/iort.md Demonstrates how to use IorT with synchronous operations for validating an address, combining log messages and results using a for-comprehension. ```scala import cats.data.Ior import cats.data.{ NonEmptyChain => Nec } import cats.syntax.all._ import scala.util.{Success, Try} type Logs = Nec[String] def parseNumber(input: String): Ior[Logs, Option[Int]] = Try(input.trim.toInt) match { case Success(number) if number > 0 => Ior.Right(Some(number)) case Success(_) => Ior.Both(Nec.one(s"'$input' is non-positive number"), None) case _ => Ior.Both(Nec.one(s"'$input' is not a number"), None) } def parseStreet(input: String): Ior[Logs, String] = { if (input.trim.isEmpty) Ior.Left(Nec.one(s"'$input' is not a street")) else Ior.Right(input) } def numberToString(number: Option[Int]): Ior[Logs, String] = number match { case Some(n) => Ior.Right(n.toString) case None => Ior.Both(Nec.one("used default address number"), "n/a") } def addressProgram(numberInput: String, streetInput: String): Ior[Logs, String] = for { number <- parseNumber(numberInput) street <- parseStreet(streetInput) sNumber <- numberToString(number) } yield s"$sNumber, $street" ``` -------------------------------- ### Functor Instance for Option Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/functor.md Provides an example implementation of the Functor type class for the Option type constructor. ```scala // Example implementation for Option implicit val functorForOption: Functor[Option] = new Functor[Option] { def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa match { case None => None case Some(a) => Some(f(a)) } } ``` -------------------------------- ### Synchronous IorT Program Execution Examples Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/iort.md Shows the results of executing the synchronous addressProgram with different inputs, illustrating how IorT combines logs and results. ```scala addressProgram("7", "Buckingham Palace Rd") addressProgram("SW1W", "Buckingham Palace Rd") addressProgram("SW1W", "") ``` -------------------------------- ### Map Semigroup Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/semigroup.md Illustrates the Semigroup instance for Maps, combining values for common keys. Shows both explicit combine and infix syntax. ```Scala import cats.syntax.all._ val map1 = Map("hello" -> 1, "world" -> 1) val map2 = Map("hello" -> 2, "cats" -> 3) ``` ```Scala Semigroup[Map[String, Int]].combine(map1, map2) map1 |+| map2 ``` -------------------------------- ### OptionT for-comprehension example Source: https://github.com/typelevel/cats/blob/main/docs/jump_start_guide.md Illustrates using OptionT within a for-comprehension to chain operations that may fail (return None). ```scala class Money { /* ... */ } def findUserById(userId: Long): OptionT[Future, User] = { /* ... */ ??? } def findAccountById(accountId: Long): OptionT[Future, Account] = { /* ... */ ??? } def getReservedFundsForAccount(account: Account): OptionT[Future, Money] = { /* ... */ ??? } def getReservedFundsForUser(userId: Long): OptionT[Future, Money] = for { user <- findUserById(userId) account <- findAccountById(user.accountId) funds <- getReservedFundsForAccount(account) } yield funds ``` -------------------------------- ### FreeApplicative foldMap Function Application Loop Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/freeapplicative.md Demonstrates the function application loop within FreeApplicative#foldMap, showing how functions are applied to arguments from the stacks after the re-association phase. ```scala ===> loop. 1A / \ arg/ \fun / \ / \ 2A 3A arg/ \fun arg/ \fun / \ / \ 4L 5P '6L 7L args: 2A :: Nil functions: Fn(gab = foldArg(7L) ap foldArg(6L), argc = 1) :: Nil ===> finished. ``` -------------------------------- ### CsvCodec Law Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/invariantmonoidal.md Illustrates a law for CsvCodec ensuring that reading the CSV representation of a value and then writing it back results in the original value. ```scala forAll { (c: CsvCodec[A], a: A) => c.read(c.write(a)) == ((Some(a), List())) ``` -------------------------------- ### Using ContravariantMonoidal with Predicates: Contramapping Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/contravariantmonoidal.md Demonstrates how to use the contramap method on a Predicate to adapt it to a different type. This example creates a Predicate for Money based on a Predicate for Long. ```scala case class Money(value: Long) def isEven: Predicate[Long] = Predicate(_ % 2 == 0) def isEvenMoney: Predicate[Money] = isEven.contramap(_.value) isEvenMoney.run(Money(55)) ``` -------------------------------- ### Asynchronous IorT Program Setup Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/iort.md Defines asynchronous versions of parsing functions returning Future[Ior[Logs, *]] and a helper function to compose them. ```scala import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global def parseNumberAsync(input: String): Future[Ior[Logs, Option[Int]]] = Future.successful(parseNumber(input)) def parseStreetAsync(input: String): Future[Ior[Logs, String]] = Future.successful(parseStreet(input)) def numberToStringAsync(number: Option[Int]): Future[Ior[Logs, String]] = Future.successful(numberToString(number)) def programHelper(number: Option[Int], streetInput: String): Future[Ior[Logs, String]] = parseStreetAsync(streetInput).flatMap { streetIor => numberToStringAsync(number).map { sNumberIor => for { street <- streetIor sNumber <- sNumberIor } yield s"$sNumber, $street" } } def addressProgramAsync(numberInput: String, streetInput: String): Future[Ior[Logs, String]] = parseNumberAsync(numberInput).flatMap { case Ior.Left(logs) => Future.successful(Ior.Left(logs)) case Ior.Right(number) => programHelper(number, streetInput) case b @ Ior.Both(_, number) => programHelper(number, streetInput).map(s => b.flatMap(_ => s)) } ``` -------------------------------- ### Clone the Cats Repository Source: https://github.com/typelevel/cats/blob/main/CONTRIBUTING.md To start contributing, clone the Cats project locally using Git. This command fetches the entire project history and files. ```shell git clone git@github.com:typelevel/cats.git ``` -------------------------------- ### Vector Alternative Instance Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/alternative.md Demonstrates the usage of the Alternative type class with the Vector type. Shows how to create empty vectors, pure values, combine vectors, and use ap for computations. ```scala import cats.Alternative import cats.syntax.all._ val empty = Alternative[Vector].empty[Int] val pureOfFive = 5.pure[Vector] val concatenated = 7.pure[Vector] <+> 8.pure[Vector] val double: Int => Int = _ * 2 val addFive: Int => Int = _ + 5 val apForVectors = (double.pure[Vector] <+> addFive.pure[Vector]) ap concatenated ``` -------------------------------- ### Lens with get Derived from modifyF Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/const.md Completes the Lens definition by deriving the get method using modifyF and cats.data.Const. ```scala import cats.Id trait Lens[S, A] { def modifyF[F[_] : Functor](s: S)(f: A => F[A]): F[S] def set(s: S, a: A): S = modify(s)(_ => a) def modify(s: S)(f: A => A): S = modifyF[Id](s)(f) def get(s: S): A = { val storedValue = modifyF[Const[A, *]](s)(a => Const(a)) storedValue.getConst } } ``` -------------------------------- ### Setup for Parallel Validation with NonEmptyChain Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/validated.md Sets up implicit instances and values for performing parallel validation using NonEmptyChain for error accumulation. Includes Read instances and a Semigroup for NonEmptyChain. ```scala import cats.SemigroupK import cats.data.NonEmptyChain import cats.syntax.all._ case class ConnectionParams(url: String, port: Int) val config = Config(Map(("endpoint", "127.0.0.1"), ("port", "not an int"))) implicit val necSemigroup: Semigroup[NonEmptyChain[ConfigError]] = SemigroupK[NonEmptyChain].algebra[ConfigError] implicit val readString: Read[String] = Read.stringRead implicit val readInt: Read[Int] = Read.intRead ``` -------------------------------- ### FreeApplicative foldMap Re-association Loop Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/freeapplicative.md Illustrates the re-association loop within FreeApplicative#foldMap by showing the state of argument and function stacks as an example FreeApplicative value is processed. ```scala ===> begin. '1A / \ arg/ \fun / \ / \ 2A 3A arg/ \fun arg/ \fun / \ / \ 4L 5P 6L 7L args: Nil functions: Nil ===> loop. 1A / \ arg/ \fun / \ / \ 2A '3A arg/ \fun arg/ \fun / \ / \ 4L 5P 6L 7L args: 2A :: Nil functions: Nil ===> loop. 1A / \ arg/ \fun / \ / \ 2A 3A arg/ \fun arg/ \fun / \ / \ 4L 5P 6L '7L args: 6L :: 2A :: Nil functions: Fn(gab = foldArg(7L), argc = 2) :: Nil ===> finished. ``` -------------------------------- ### Reducible NonEmptyIntercalate Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Shows how to intercalate elements of a NonEmptyList with a separator. ```scala Reducible[NonEmptyList].nonEmptyIntercalate(NonEmptyList.of("a", "b", "c"), ", ") ``` -------------------------------- ### Creating Show Instances for Case Classes Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/show.md Illustrates how to create Show instances for case classes using the `show` and `fromToString` helper functions. Requires importing cats.Show. ```scala import cats.Show case class Person(name: String, age: Int) implicit val showPerson: Show[Person] = Show.show(person => person.name) case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString ``` -------------------------------- ### Clean and Package Project Source: https://github.com/typelevel/cats/blob/main/PROCESS.md Before initiating the release process, run these commands to ensure a clean build environment and verify that all project components can be successfully packaged. ```shell + clean ``` ```shell + package ``` -------------------------------- ### Reducible ReduceLeft Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Demonstrates the left-associative reduction ('reduceLeft') on a NonEmptyVector. ```scala Reducible[NonEmptyVector].reduceLeft(NonEmptyVector.of(1,2,3,4))((s,i) => s + i) ``` -------------------------------- ### Generate Documentation Site Source: https://github.com/typelevel/cats/blob/main/CONTRIBUTING.md Use this sbt command to generate the documentation site. ```shell sbt docs/tlSite ``` -------------------------------- ### Reducible ReduceK Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Illustrates 'reduceK' for reducing a NonEmptyVector of lists. ```scala Reducible[NonEmptyVector].reduceK(NonEmptyVector.of(List(1,2,3), List(2,3,4))) ``` -------------------------------- ### Reducible NonEmptyTraverse_ Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Demonstrates 'nonEmptyTraverse_' for traversing a NonEmptyList with an effectful operation. ```scala def countChars(s: String) = s.toCharArray.groupBy(identity).view.mapValues(_.length).toMap Reducible[NonEmptyList].nonEmptyTraverse_(NonEmptyList.of("Hello", "World"))(countChars) ``` -------------------------------- ### Inferring Type Parameter with Partially Applied Type Source: https://github.com/typelevel/cats/blob/main/docs/guidelines.md This example shows how to use the `OptionT.pure` function after implementing the partially applied type technique, allowing the type parameter `A` to be inferred. ```Scala OptionT.pure[List](1) ``` -------------------------------- ### Using Show Syntax: The show Method Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/show.md Demonstrates the usage of the `show` syntax, which adds a `show` method to any type with a Show instance in scope. Requires importing cats.syntax.all. ```scala import cats.syntax.all._ val john = Person("John", 31) john.show ``` -------------------------------- ### Create Ior values Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/ior.md Demonstrates creating Ior instances using Ior.left, Ior.right, and Ior.both. ```Scala import cats.data._ val right = Ior.right[String, Int](3) val left = Ior.left[String, Int]("Error") val both = Ior.both("Warning", 3) ``` -------------------------------- ### Using Show Syntax: The show String Interpolator Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/show.md Shows how to use the `show"..."` string interpolator, which functions like the standard `s"..."` interpolator but utilizes Show instances for conversions. ```scala val engineering = Department(2, "Engineering") show"$john works at $engineering" ``` -------------------------------- ### Reducible NonEmptySequence_ Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Shows 'nonEmptySequence_' for sequencing effectful computations within a NonEmptyList of Maps. ```scala Reducible[NonEmptyList].nonEmptySequence_(NonEmptyList.of(Map(1 -> 'o'), Map(1 -> 'o'))) ``` -------------------------------- ### Use .some Syntax for Option Source: https://github.com/typelevel/cats/blob/main/docs/jump_start_guide.md Demonstrates using the .some syntax helper for creating Option values, which is more readable than Some(value) when chaining with other operations like .asFuture. ```Scala class Account { /* ... */ } trait AccountService { def getAccountById(id: Int): Future[Option[Account]] } class DummyAccountServiceImpl extends AccountService { def dummyAccount: Account = ??? /* ... */ override def getAccountById(id: Int): Future[Option[Account]] = dummyAccount.some.asFuture /* ... */ } ``` -------------------------------- ### Using make with NonEmptyList Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/bimonad.md Demonstrates the 'make' function with a NonEmptyList containing a single configuration string. ```scala make(NonEmptyList.one("config")) ``` -------------------------------- ### Basic Lens Trait Definition Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/const.md Defines the fundamental structure of a Lens with get, set, and modify methods. ```scala trait Lens[S, A] { def get(s: S): A def set(s: S, a: A): S def modify(s: S)(f: A => A): S = set(s, f(get(s))) } ``` -------------------------------- ### Test Scalafix Rules Source: https://github.com/typelevel/cats/blob/main/scalafix/README.md Navigate to the scalafix directory and run the test command to verify the Scalafix rules. ```bash cd scalafix sbt test ``` -------------------------------- ### Define Futures and Processing Function Source: https://github.com/typelevel/cats/blob/main/docs/jump_start_guide.md Sets up necessary Future definitions and a processing function for subsequent examples. ```scala import scala.concurrent.ExecutionContext.Implicits.global class ProcessingResult { /* ... */ } def intFuture: Future[Int] = { /* ... */ ??? } def stringFuture: Future[String] = { /* ... */ ??? } def userFuture: Future[User] = { /* ... */ ??? } def process(value: Int, contents: String, user: User): ProcessingResult = { /* ... */ ??? } ``` -------------------------------- ### Reducible Lazy ReduceRightTo Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Demonstrates 'reduceRightTo' which combines mapping and lazy right-associative reduction on a NonEmptyList. ```scala Reducible[NonEmptyList].reduceRightTo(NonEmptyList.of(1,2,3,4))(_.toString)((i,s) => Later(s.value + i)).value ``` -------------------------------- ### Reducible Lazy ReduceRight Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/reducible.md Shows the lazy, right-associative reduction ('reduceRight') using Eval on a NonEmptyList. ```scala Reducible[NonEmptyList].reduceRight(NonEmptyList.of(1,2,3,4))((i,s) => Later(s.value + i)).value ``` -------------------------------- ### Creating OptionT with Pure and None Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/optiont.md Shows how to create an OptionT using OptionT.pure (or OptionT.some) for a successful value and OptionT.none for a failed or empty case. ```scala import cats.data.OptionT import scala.concurrent.Future val greet: OptionT[Future,String] = OptionT.pure("Hola!") val greetAlt: OptionT[Future,String] = OptionT.some("Hi!") val failedGreet: OptionT[Future,String] = OptionT.none ``` -------------------------------- ### Import Cats Syntax Source: https://github.com/typelevel/cats/blob/main/docs/jump_start_guide.md Import this to enable Cats syntax helpers like .some and .asRight. ```Scala import cats.syntax.all._ ``` -------------------------------- ### Use .asRight Syntax for Either Source: https://github.com/typelevel/cats/blob/main/docs/jump_start_guide.md Shows how to use the .asRight syntax helper for creating Right values in Either, which can be combined with .asFuture for improved readability compared to Future.successful(Right(value)). ```Scala case class User(accountId: Long) { /* ... */ } trait UserService { def ensureUserExists(id: Int): Future[Either[Exception, User]] } class UserServiceSpec extends UserService { def dummyUser: User = ??? /* ... */ override def ensureUserExists(id: Int): Future[Either[Exception, User]] = dummyUser.asRight.asFuture // instead of Future.successful(Right(dummyUser)) /* ... */ } ``` -------------------------------- ### Validate user data with Ior Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/ior.md Example of accumulating validation warnings and errors using Ior and NonEmptyChain. ```Scala import cats.syntax.all._ import cats.data.{ NonEmptyChain => Nec, Ior} type Failures = Nec[String] case class Username(value: String) extends AnyVal case class Password(value: String) extends AnyVal case class User(name: Username, pw: Password) def validateUsername(u: String): Failures Ior Username = { if (u.isEmpty) Nec.one("Can't be empty").leftIor else if (u.contains(".")) Ior.both(Nec.one("Dot in name is deprecated"), Username(u)) else Username(u).rightIor } def validatePassword(p: String): Failures Ior Password = { if (p.length < 8) Nec.one("Password too short").leftIor else if (p.length < 10) Ior.both(Nec.one("Password should be longer"), Password(p)) else Password(p).rightIor } def validateUser(name: String, password: String): Failures Ior User = (validateUsername(name), validatePassword(password)).mapN(User) ``` -------------------------------- ### Create Robot using State and for-comprehension Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/state.md Illustrates building a complex State computation for creating a Robot by sequencing multiple State operations (nextLong, nextBoolean) using a for-comprehension. This leverages `flatMap` implicitly. ```scala val createRobot: State[Seed, Robot] = for { id <- nextLong sentient <- nextBoolean isCatherine <- nextBoolean name = if (isCatherine) "Catherine" else "Carlos" isReplicant <- nextBoolean model = if (isReplicant) "replicant" else "borg" } yield Robot(id, sentient, name, model) ``` -------------------------------- ### Lifting Values into OptionT Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/optiont.md Demonstrates how to create an OptionT from existing Option and Future values using OptionT.fromOption and OptionT.liftF within a for-comprehension. ```scala import cats.data.OptionT import scala.concurrent.Future val greetingFO: Future[Option[String]] = Future.successful(Some("Hello")) val firstnameF: Future[String] = Future.successful("Jane") val lastnameO: Option[String] = Some("Doe") val ot: OptionT[Future, String] = for { g <- OptionT(greetingFO) f <- OptionT.liftF(firstnameF) l <- OptionT.fromOption[Future](lastnameO) } yield s"$g $f $l" val result: Future[Option[String]] = ot.value // Future(Some("Hello Jane Doe")) ``` -------------------------------- ### Get Temperature by City Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/applicativemonaderror.md A function that returns the temperature for a given city. It uses ApplicativeError to wrap the result in a monadic context. ```scala def getTemperatureByCity[F[_]](city: String)(implicit ae: ApplicativeError[F, String]): F[Int] = { ae.pure(78) } ``` -------------------------------- ### Validated Applicative Behavior Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/validated.md Demonstrates the short-circuiting behavior of the ap method when used with two invalid Validated instances. ```scala validatedMonad.tuple2(Validated.invalidNec[String, Int]("oops"), Validated.invalidNec[String, Double]("uh oh")) ``` -------------------------------- ### Create IorNec instance Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/ior.md Shows how to create an IorNec instance using Ior.fromEither with a left-biased NonEmptyChain. ```Scala import cats.syntax.all._, cats.data.NonEmptyChain val left: IorNec[String, Int] = Ior.fromEither("Error".leftNec[Int]) ``` -------------------------------- ### Implement open Action with Basic State Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/state.md Shows an implementation of the 'open' action using the basic State monad. It highlights the challenge of handling invalid states (e.g., trying to open an already open door) and the need for a more robust solution. ```scala val openImpl: State[DoorState, Unit] = State { doorState => doorState match { case Closed => (Open, ()) case Open => ??? // What now? } } ``` -------------------------------- ### Using make with Function0 Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/bimonad.md Shows the 'make' function's compatibility with Function0, another lawful Bimonad. ```scala make(() => "config") ``` -------------------------------- ### MUnit Test for Functor Laws Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/lawtesting.md Example of using `DisciplineSuite` with MUnit to test the Functor laws for the `Tree` data type. ```scala import cats.syntax.all._ import cats.laws.discipline.FunctorTests import munit.DisciplineSuite import arbitraries._ class TreeLawTests extends DisciplineSuite { checkAll("Tree.FunctorLaws", FunctorTests[Tree].functor[Int, Int, String]) } ``` -------------------------------- ### Stack-Safe Monadic Recursion with tailRecM for Option Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/monad.md An example of a Monad instance for Option that implements tailRecM with a tail-recursive and stack-safe approach. ```scala import cats.Monad import scala.annotation.tailrec implicit val optionMonad: Monad[Option] = new Monad[Option] { def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] = fa.flatMap(f) def pure[A](a: A): Option[A] = Some(a) @tailrec def tailRecM[A, B](a: A)(f: A => Option[Either[A, B]]): Option[B] = f(a) match { case None => None case Some(Left(nextA)) => tailRecM(nextA)(f) // continue the recursion case Some(Right(b)) => Some(b) // recursion done } } ``` -------------------------------- ### Define Tree Data Type and Functor Instance Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/lawtesting.md Example of creating a custom data type `Tree` and its `Functor` instance. ```scala import cats._ sealed trait Tree[+A] case object Leaf extends Tree[Nothing] case class Node[A](p: A, left: Tree[A], right: Tree[A]) extends Tree[A] object Tree { implicit val functorTree: Functor[Tree] = new Functor[Tree] { def map[A, B](tree: Tree[A])(f: A => B) = tree match { case Leaf => Leaf case Node(p, left, right) => Node(f(p), map(left)(f), map(right)(f)) } } } ``` -------------------------------- ### Applicative Implementation for Either Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/applicative.md Provides an example implementation of the Applicative type class for the right-biased `Either[L, *]` type constructor. ```scala implicit def applicativeForEither[L]: Applicative[Either[L, *]] = new Applicative[Either[L, *]] { def product[A, B](fa: Either[L, A], fb: Either[L, B]): Either[L, (A, B)] = (fa, fb) match { case (Right(a), Right(b)) => Right((a, b)) case (Left(l) , _ ) => Left(l) case (_ , Left(l) ) => Left(l) } def pure[A](a: A): Either[L, A] = Right(a) def map[A, B](fa: Either[L, A])(f: A => B): Either[L, B] = fa match { case Right(a) => Right(f(a)) case Left(l) => Left(l) } } ``` -------------------------------- ### Define DoorState and Basic State Actions Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/state.md Sets up the basic types for modeling a door's state (Open, Closed) and defines placeholder State actions for opening and closing. This serves as a starting point for demonstrating type-safe state transitions. ```scala sealed trait DoorState case object Open extends DoorState case object Closed extends DoorState case class Door(state: DoorState) def open: State[DoorState, Unit] = ??? def close: State[DoorState, Unit] = ??? ``` -------------------------------- ### Converting Option or F[Option] to IorT Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/iort.md Demonstrates creating IorT from Option[B] using IorT.fromOption and from F[Option[B]] using IorT.fromOptionF. IorT.fromOptionM handles F[Option[B]] with a default F[A]. ```scala val numberOption: Option[Int] = None val numberFOption: List[Option[Int]] = List(None, Some(2), None, Some(5)) val number = IorT.fromOption[List](numberOption, "Not defined") val numberF = IorT.fromOptionF(numberFOption, "Not defined") val numberM = IorT.fromOptionM(numberFOption, List("Not defined")) ``` -------------------------------- ### Examples of user validation results Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/ior.md Illustrates different outcomes of the user validation function, showing success, warnings, and errors. ```Scala validateUser("John", "password12") validateUser("john.doe", "password") validateUser("jane", "short") ``` -------------------------------- ### Accumulating Function using FancyFunction Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/arrow.md Creates a stateful FancyFunction that accumulates values using a given function and starting value. ```scala def accum[A, B](b: B)(f: (A, B) => B): FancyFunction[A, B] = FancyFunction {a => val b2 = f(a, b) (accum(b2)(f), b2) } ``` -------------------------------- ### Using make with Eval Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/bimonad.md Illustrates the 'make' function's usage with Eval, a lawful Bimonad. ```scala make(Eval.later("config")) ``` -------------------------------- ### Pair with Subtyping Constraints (Illustrative) Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses.md An illustrative example of a Pair case class with subtyping constraints, showing a more complex type signature. ```Scala final case class Pair[A <: Monoid[A], B <: Monoid[B]](first: A, second: B) extends Monoid[Pair[A, B]] { def empty: Pair[A, B] = ??? def combine(x: Pair[A, B], y: Pair[A, B]): Pair[A, B] = ??? ``` -------------------------------- ### Successful Form Validation Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/validated.md Demonstrates a successful form validation using FormValidatorNec.validateForm with valid inputs, resulting in a RegistrationData instance. ```scala FormValidatorNec.validateForm( username = "Joe", password = "Passw0r$1234", firstName = "John", lastName = "Doe", age = 21 ) ``` -------------------------------- ### Using Eq symbolic operators Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/eq.md Shows how to use the `===` (equals) and `=!=` (not equals) symbolic operators provided by the `cats.syntax.all._` package for type-safe comparisons. ```scala import cats.syntax.all._ 1 === 1 "Hello" =!= "World" ``` -------------------------------- ### Lazy Right Fold Example Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/foldable.md Illustrates the necessity of lazy `foldRight` with `Eval` to handle infinite structures and prevent stack overflows. ```scala val allFalse = LazyList.continually(false) // beware! throws OutOfMemoryError, which is irrecoverable // allFalse.foldRight(true)(_ && _) ``` ```scala import cats.Eval // This calculation terminates due to lazy evaluation with Eval // Foldable[LazyList].foldRight(allFalse, Eval.now(true))((a, b) => Eval.now(a && b.value)).value ``` -------------------------------- ### Get Closest City to Coordinates Source: https://github.com/typelevel/cats/blob/main/docs/typeclasses/applicativemonaderror.md A function that returns a city name based on coordinates. It uses ApplicativeError to wrap the result in a monadic context. ```scala def getCityClosestToCoordinate[F[_]](x: (Int, Int))(implicit ae: ApplicativeError[F, String]): F[String] = { ae.pure("Minneapolis, MN") } ``` -------------------------------- ### Executing Asynchronous IorT Programs Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/iort.md Demonstrates how to execute the asynchronous IorT program with different inputs and await the results. This shows how to handle the 'value' of the IorT. ```scala Await.result(addressProgramAsyncIorT("7", "Buckingham Palace Rd").value, 1.second) Await.result(addressProgramAsyncIorT("SW1W", "Buckingham Palace Rd").value, 1.second) Await.result(addressProgramAsyncIorT("SW1W", "").value, 1.second) ``` -------------------------------- ### Failed Form Validation Example Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/validated.md Demonstrates a failed form validation using FormValidatorNec.validateForm with invalid inputs, resulting in a NonEmptyChain of DomainValidation errors. ```scala FormValidatorNec.validateForm( username = "Joe%%%", password = "password", firstName = "John", lastName = "Doe", age = 21 ) ``` -------------------------------- ### FreeT with OptionT and Try Interpreter Source: https://github.com/typelevel/cats/blob/main/docs/datatypes/freemonad.md Illustrates using FreeT with OptionT for boilerplate reduction and a Try interpreter for context. This example combines lifting effects from Ctx into OptionT and then folding map to evaluate. ```Scala import cats.free._ import cats._ import cats.data._ import cats.syntax.all._ import scala.util.Try sealed trait Ctx[A] case class Action(value: Int) extends Ctx[Int] def op1: FreeT[Ctx, Option, Int] = FreeT.liftF[Ctx, Option, Int](Action(7)) def op2: FreeT[Ctx, Option, Int] = FreeT.liftT[Ctx, Option, Int](Some(4)) def op3: FreeT[Ctx, Option, Int] = FreeT.pure[Ctx, Option, Int](1) val opComplete: FreeT[Ctx, Option, Int] = for { a <- op1 b <- op2 c <- op3 } yield a + b + c /* Our interpreters */ type OptTry[A] = OptionT[Try, A] def tryInterpreter: Ctx ~> OptTry = new (Ctx ~> OptTry) { def apply[A](fa: Ctx[A]): OptTry[A] = { fa match { case Action(value) => OptionT.liftF(Try(value)) } } } def optTryLift: Option ~> OptTry = new (Option ~> OptTry) { def apply[A](fa: Option[A]): OptTry[A] = { fa match { case Some(value) => OptionT(Try(Option(value))) case None => OptionT.none } } } val hoisted = opComplete.hoist(optTryLift) val evaluated = hoisted.foldMap(tryInterpreter) val result = evaluated.value ```