### Example Functions Source: https://arrow-kt.io/learn/typed-errors/from-either-to-raise These are example functions used throughout the guide. They return Either types or String. ```kotlin fun f(n: Int): Either fun g(s: String): Either fun h(s: String): Either fun Thing.summarize(): String ``` -------------------------------- ### Install Resources with ResourceScope Source: https://arrow-kt.io/learn/coroutines/resource-safety Acquires and releases resources within a `resourceScope`. Demonstrates parallel acquisition using `parZip`. The `install` function takes acquisition and release steps, ensuring the finalizer runs on exit. ```kotlin suspend fun ResourceScope.userProcessor(): UserProcessor = install({ UserProcessor().also { it.start() } }) { p, _ -> p.shutdown() } suspend fun ResourceScope.dataSource(): DataSource = install({ DataSource().also { it.connect() } }) { ds, _ -> ds.close() } suspend fun example(): Unit = resourceScope { val service = parZip({ userProcessor() }, { dataSource() }) { userProcessor, ds -> Service(ds, userProcessor) } val data = service.processData() println(data) } ``` -------------------------------- ### Define Resource using Install within Resource Block Source: https://arrow-kt.io/learn/coroutines/resource-safety Shows an alternative way to define a `Resource` by using the `install` function within a `resource` block that has `ResourceScope` as a receiver. ```kotlin val userProcessor: Resource = resource { val x: UserProcessor = install( { UserProcessor().also { it.start() } }, { processor, _ -> processor.shutdown() } ) x } ``` -------------------------------- ### Example Tree Construction and Leaf Value Traversal Source: https://arrow-kt.io/learn/immutable-data/regex Constructs an example binary tree and demonstrates a traversal that focuses on the values within the leaves. The path is defined using zeroOrMore and every, then targets leaf values. ```kotlin val exampleTree2 = Node2(1, Node2(2, Leaf2(3), Leaf2(4)), Leaf2(5)) fun example() { val path = zeroOrMore(BinaryTree2.node2().children().every).leaf2().value() val modifiedTree2 = path.modify(exampleTree2) { it + 1 } modifiedTree2 shouldBe Node2(1, Node2(2, Leaf2(4), Leaf2(5)), Leaf2(6)) } ``` -------------------------------- ### Example Usage of LCE DSL Source: https://arrow-kt.io/learn/typed-errors/wrappers/own-error-types Demonstrates using the custom lce DSL for composing computations with LCE values. Includes examples of successful computation and error short-circuiting with ensure. ```kotlin fun example() { lce { val a = Lce.Content(1).bind() val b = Lce.Content(1).bind() a + b } shouldBe Lce.Content(2) lce { val a = Lce.Content(1).bind() ensure(a > 1) { Lce.Failure("a is not greater than 1") } a + 1 } shouldBe Lce.Failure("a is not greater than 1") } ``` -------------------------------- ### IO> Program Example Source: https://arrow-kt.io/learn/design/suspend-io Demonstrates how to compose IO effects to fetch and process a user, handling potential domain errors. Includes an unwrapped suspend version. ```kotlin import arrow.fx.* fun ioProgram(): IO> = IO.fx { val res = !IO.effect { fetchUser() } !res.fold({ IO.just(Either.Left(error)) }, { user -> IO.effect { user.process() } }) } // Or unwrapped in `suspend` suspend suspendedIOProgram(): Either = ioProgram().suspended() ``` -------------------------------- ### Arrow IO Example Source: https://arrow-kt.io/learn/design/suspend-io Illustrates a simple IO program using Arrow's IO data type to perform sequential operations. ```kotlin import arrow.fx.IO fun number(): IO = IO.pure(1) fun triple(): IO> = number().flatMap { a -> number().flatMap { b -> number().map { c -> Triple(a, b, c) } } } ``` -------------------------------- ### Manage Resources with Auto-Closing in Kotlin Source: https://arrow-kt.io/learn/quickstart Use the `resourceScope` and `autoCloseable` to safely acquire and release resources like `HttpClient` that implement `AutoCloseable`. The `install` function allows for custom resource setup and cleanup. ```kotlin suspend fun main(): Unit = resourceScope { // register several resources val client = autoCloseable { HttpClient() } // compatible with 'AutoCloseable' val dataSource = install({ DataSource(client) }) { s, _ -> s.disconnect() } // use dataSource here } ``` -------------------------------- ### Example Usage with Multiple Contexts (Initial Attempt) Source: https://arrow-kt.io/learn/design/effects-contexts An initial attempt to call saveUserInDb, which fails because it doesn't pack the required Database and Log instances into a single context object. ```kotlin suspend fun example() { db(connParams) { stdoutLogger { saveUserInDb(User("Alex")) } } } ``` -------------------------------- ### Future Context Parameters Example Source: https://arrow-kt.io/learn/design/effects-contexts Demonstrates the future syntax for context parameters in Kotlin, which allows for a cleaner design compared to using 'where' clauses for subtyping. ```kotlin context(db: Database, logger: Logger) fun User.saveInDb() { ... } ``` -------------------------------- ### JVM `Closeable` Resource Usage Example Source: https://arrow-kt.io/learn/coroutines/resource-safety Shows how to use `Closeable` and `use` blocks on JVM to manage resources, highlighting its limitations for Multiplatform and composability. ```kotlin suspend fun example() { UserProcessor().use { userProcessor -> userProcessor.start() DataSource().use { dataSource -> dataSource.connect() Service(dataSource, userProcessor).processData() } } } ``` -------------------------------- ### Simple Graceful Shutdown Example Source: https://arrow-kt.io/learn/coroutines/suspendapp Demonstrates a basic application loop that handles cancellation exceptions to perform cleanup. Press Ctrl+C to trigger the shutdown sequence. ```kotlin import arrow.continuations.SuspendApp import kotlinx.coroutines.CancellationException import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.delay import kotlinx.coroutines.withContext fun main() = SuspendApp { try { println("App Started! Waiting until asked to shutdown.") while (true) { delay(2_500) println("Ping") } } catch (e: CancellationException) { println("Cleaning up App... will take 10 seconds...") withContext(NonCancellable) { delay(10_000) } println("Done cleaning up. Will release app to exit") } } ``` -------------------------------- ### Basic Racing DSL Example Source: https://arrow-kt.io/learn/coroutines/racing Demonstrates the fundamental usage of the racing DSL to concurrently fetch user data from remote and local caches. The first successful result is returned. ```kotlin suspend fun getUserRacing(id: UserId): User = racing { race { RemoteCache.getUser(id) } race { LocalCache.getUser(id) } } ``` -------------------------------- ### Gradle Kotlin DSL Setup for Arrow Optics Source: https://arrow-kt.io/learn/quickstart/setup Configure your Gradle build script using Kotlin DSL to include the KSP plugin and Arrow Optics dependencies. This setup is required for deriving optics boilerplate. ```kotlin plugins { id("com.google.devtools.ksp") version "2.3.4" } dependencies { implementation("io.arrow-kt:arrow-optics:2.2.3") ksp("io.arrow-kt:arrow-optics-ksp-plugin:2.2.3") } ``` -------------------------------- ### Gradle Groovy DSL Setup for Arrow Optics Source: https://arrow-kt.io/learn/quickstart/setup Configure your Gradle build script using Groovy DSL to include the KSP plugin and Arrow Optics dependencies. This setup is required for deriving optics boilerplate. ```groovy plugins { id 'com.google.devtools.ksp' version '2.3.4' } dependencies { implementation 'io.arrow-kt:arrow-optics:2.2.3' ksp 'io.arrow-kt:arrow-optics-ksp-plugin:2.2.3' } ``` -------------------------------- ### Function Signatures for Raise DSL Source: https://arrow-kt.io/learn/typed-errors/from-either-to-raise These are example function signatures demonstrating the use of the Raise DSL with different error types and return values. ```kotlin fun Raise.f(n: Int): String fun Raise.g(s: String): Thing fun Raise.h(s: String): Thing fun Thing.summarize(): String ``` -------------------------------- ### Suspend Function Example in Kotlin Source: https://arrow-kt.io/learn/design/suspend-io Shows how to achieve the same result as the `IO` example using Kotlin's `suspend` functions. This approach allows for more direct and readable code construction without explicit monad operations like `flatMap`. ```kotlin suspend fun number(): Int = 1 suspend fun triple(): Triple = Triple(number(), number(), number()) ``` -------------------------------- ### Example of Short-Circuiting Validation Source: https://arrow-kt.io/learn/typed-errors/working-with-typed-errors Demonstrates how the smart constructor fails on the first validation error. ```kotlin fun example() { User("", -1) shouldBe Left(UserProblem.EmptyName) } ``` -------------------------------- ### Unsafe Resource Usage Example Source: https://arrow-kt.io/learn/coroutines/resource-safety Demonstrates a scenario where resources (`dataSource`, `userProcessor`) are not properly closed, leading to potential leaks when `processData` throws an exception. ```kotlin suspend fun example() { val userProcessor = UserProcessor().also { it.start() } val dataSource = DataSource().also { it.connect() } val service = Service(dataSource, userProcessor) service.processData() dataSource.close() userProcessor.shutdown() } ``` -------------------------------- ### Corrected firstOrElse examples with Option Source: https://arrow-kt.io/learn/typed-errors/wrappers/nullable-and-option These examples demonstrate that the `firstOrElse` function, when implemented using Arrow's Option type, now behaves as expected across all cases, including empty lists, lists with non-null first elements, and lists with `null` as the first element. ```kotlin fun example() { emptyList().firstOrElse { -1 } shouldBe -1 listOf(1, null, 3).firstOrElse { -1 } shouldBe 1 listOf(null, 2, 3).firstOrElse { -1 } shouldBe null } ``` -------------------------------- ### Example of deprecated Ior traverse usage Source: https://arrow-kt.io/learn/quickstart/migration Demonstrates the usage of the deprecated traverse method with an Ior.Right value and an evenOpt function. ```kotlin fun evenOpt(i: Int): Option = if(i % 2 == 0) i.some() else None fun deprecatedTraverse() { val rightIor: Ior = Ior.Right(124) val result = rightIor.traverse { evenOpt(it) } result shouldBe Some(Ior.Right(124)) } ``` -------------------------------- ### Migrate Zip to Bind with Intermediate Variables Source: https://arrow-kt.io/learn/quickstart/migration An alternative to the direct `bind` summation, this example shows how to use intermediate `val` declarations within the `either` DSL when migrating from `zip`. This can improve readability for more complex operations. ```kotlin fun one(): Either = Either.Right(1) val new2 : Either = either { val x = one().bind() val y = one().bind() x + y } ``` -------------------------------- ### Composing Either Computations with Raise DSL Source: https://arrow-kt.io/learn/typed-errors/from-either-to-raise This example shows how to compose computations using the Raise DSL, where the error type is the extension receiver. It avoids explicit `bind` calls. ```kotlin fun Raise.bar(n: Int): String { val s = f(n) val t = withError({ boo -> boo.toError() }) { h(s) } return t.summarize() } ``` -------------------------------- ### Define a two-argument function Source: https://arrow-kt.io/learn/collections-functions/utils A simple example of a two-argument function signature in Kotlin. ```kotlin fun dance(rounds: Int, person: String): Unit { TODO() } ``` -------------------------------- ### Define a sealed interface for Prisms Source: https://arrow-kt.io/learn/immutable-data/reflection Example of defining a sealed interface and its implementations, which are commonly used with prisms. ```kotlin sealed interface Cutlery object Fork: Cutlery object Spoon: Cutlery ``` -------------------------------- ### Example Usage with Multiple Contexts (Workaround) Source: https://arrow-kt.io/learn/design/effects-contexts A workaround for calling saveUserInDb by creating an anonymous object on the spot that delegates to the available Database and Logger instances, effectively packing them into a single context. ```kotlin suspend fun example() { db(connParams) { stdoutLogger { with(object : Database by this@db, Logger as this@stdoutLogger) { saveUserInDb(User("Alex")) } } } } ``` -------------------------------- ### Pure Function Example Source: https://arrow-kt.io/learn/design/receivers-flatmap A basic pure function that performs addition. Its return type is honest and depends solely on its input arguments. ```kotlin fun add(x: Int, y: Int): Int = x + y ``` -------------------------------- ### IO Monad Example in Arrow Kotlin Source: https://arrow-kt.io/learn/design/suspend-io Demonstrates how to chain operations using `flatMap` and `map` with the `IO` monad to return a `Triple` of numbers. This approach requires explicit handling of the `IO` wrapper. ```kotlin fun number(): IO = IO.pure(1) fun triple(): IO> = number().flatMap { a -> number().flatMap { b -> number().map { c -> Triple(a, b, c) } } } ``` -------------------------------- ### Maven Setup for Arrow Optics (Unofficial) Source: https://arrow-kt.io/learn/quickstart/setup Configure your Maven settings to include the Arrow Optics KSP plugin. Note that official KSP support in Maven is not available, and this configuration is unofficial. ```xml settings: kotlin: # other settings ksp: processors: - io.arrow-kt:arrow-optics-ksp-plugin:2.2.3 ``` -------------------------------- ### Creating an Event Instance with Nullable Fields Source: https://arrow-kt.io/learn/design/domain-modeling An example of instantiating an Event where isOnline is true, but url and address are null. This highlights a potential contract violation in the previous data class approach. ```kotlin Event( Id(0L), Title("Functional Domain Modeling"), Organizer("47 Degrees"), Description("Building software with functional DDD..."), LocalDate.now(), AgeRestriction.General, true, null, null ) ``` -------------------------------- ### Cats Effect IO Data Class Analogy Source: https://arrow-kt.io/learn/design/suspend-io Shows a conceptual translation of the Arrow IO example to a data class structure similar to Cats Effect, emphasizing the runtime construction and allocation costs. ```kotlin fun number(): IO = IO.Just(1) fun triple(): IO> = IO.FlatMap(IO.Pure(1)) { a -> IO.FlatMap(IO.Pure(1)) { b -> IO.Map(IO.Pure(1)) { c -> Triple(a, b, c) } } } ``` -------------------------------- ### CircuitBreaker with Retry Policy Source: https://arrow-kt.io/learn/resilience/circuitbreaker Shows how to compose a CircuitBreaker with a retry policy using Arrow's Schedule. This example simulates an overloaded service and demonstrates different retry strategies. ```kotlin @ExperimentalTime suspend fun main(): Unit { suspend fun apiCall(): Unit { println("apiCall . . .") throw RuntimeException("Overloaded service") } val circuitBreaker = CircuitBreaker( openingStrategy = OpeningStrategy.Count(2), resetTimeout = 2.seconds, exponentialBackoffFactor = 1.2, maxResetTimeout = 60.seconds, ) suspend fun resilient(schedule: Schedule, f: suspend () -> A): A = schedule.retry { circuitBreaker.protectOrThrow(f) } // simulate getting overloaded Either.catch { resilient(Schedule.recurs(5), ::apiCall) }.let { println("recurs(5) apiCall twice and 4x short-circuit result from CircuitBreaker: $it") } // simulate reset timeout delay(2000) println("CircuitBreaker ready to half-open") // retry once, // and when the CircuitBreaker opens after 2 failures // retry with exponential back-off with same time as CircuitBreaker's resetTimeout val fiveTimesWithBackOff = Schedule.recurs(1) andThen Schedule.exponential(2.seconds) and Schedule.recurs(5) Either.catch { resilient(fiveTimesWithBackOff, ::apiCall) }.let { println("exponential(2.seconds) and recurs(5) always retries with actual apiCall: $it") } } ``` -------------------------------- ### Verify Memoized Function Results Source: https://arrow-kt.io/learn/collections-functions/memoize This example shows how to verify that a memoized function returns the same cached result for identical inputs. The second call to `memoizedExpensive(3)` should return immediately without re-computation. ```kotlin fun example() { val result1 = memoizedExpensive(3) val result2 = memoizedExpensive(3) result1 shouldBe result2 } ``` -------------------------------- ### Racing Coroutines with `select` Source: https://arrow-kt.io/learn/coroutines/racing This example demonstrates how to race two suspend functions, `RemoteCache.getUser` and `LocalCache.getUser`, for the first successful result using the standard library's `select` expression. It includes error handling for non-fatal exceptions and ensures cancellation of other coroutines upon completion. ```kotlin object RemoteCache { suspend fun getUser(id: UserId): User = if (Random.nextBoolean()) User("$id-remote-user") else throw BadRequestException() } object LocalCache { suspend fun getUser(id: UserId): User = if (Random.nextBoolean()) User("$id-local-user") else throw NullPointerException() } suspend fun awaitAfterError(block: suspend () -> A): A = try { block() } catch (e: Throwable) { if (e is CancellationException || NonFatal(e)) throw e e.printStackTrace() awaitCancellation() } suspend fun getRemoteUser(id: UserId): User = coroutineScope { try { select { async { awaitAfterError { RemoteCache.getUser(id) } }.onAwait { it } async { awaitAfterError { LocalCache.getUser(id) } }.onAwait { it } } } finally { coroutineContext.job.cancelChildren() } } ``` -------------------------------- ### Transferring Funds Between Accounts with STM Source: https://arrow-kt.io/learn/coroutines/stm Demonstrates a banking service transferring money between two accounts using STM. Ensures atomicity and prevents race conditions. Requires initial TVar setup and the atomically block to execute the transaction. ```kotlin import arrow.fx.stm.atomically import arrow.fx.stm.TVar import arrow.fx.stm.STM fun STM.transfer(from: TVar, to: TVar, amount: Int) { withdraw(from, amount) deposit(to, amount) } fun STM.deposit(acc: TVar, amount: Int) { val current = acc.read() acc.write(current + amount) // or the shorthand acc.modify { it + amount } } fun STM.withdraw(acc: TVar, amount: Int) { val current = acc.read() require(current - amount >= 0) { "Not enough money in the account!" } acc.write(current - amount) } suspend fun example() { val acc1 = TVar.new(500) val acc2 = TVar.new(300) // check initial balances acc1.unsafeRead() shouldBe 500 acc2.unsafeRead() shouldBe 300 // perform transaction atomically { transfer(acc1, acc2, 50) } // check final balances acc1.unsafeRead() shouldBe 450 acc2.unsafeRead() shouldBe 350 } ``` -------------------------------- ### Monad Transformer Composition Example Source: https://arrow-kt.io/learn/design/receivers-flatmap Illustrates the composition of multiple effects using monad transformers like StateT, ReaderT, and IO. This approach is common in languages like Haskell and Scala for managing complex effect stacks. ```kotlin StateT[DbConnection, ReaderT[Config, IO], User] ``` -------------------------------- ### Basic Ktor Server with SuspendApp and Graceful Shutdown Source: https://arrow-kt.io/learn/coroutines/suspendapp/ktor This snippet demonstrates setting up a basic Ktor server within a SuspendApp, including routing and utilizing `awaitCancellation` for graceful shutdown hooks (SIGTERM, SIGINT). The server engine is lifted into a Resource, supporting auto-reload. ```kotlin fun main() = SuspendApp { resourceScope { server(Netty) { routing { get("/ping") { call.respond("pong") } } } awaitCancellation() } } ``` -------------------------------- ### Zip to zipOrAccumulate Example Source: https://arrow-kt.io/learn/quickstart/migration Illustrates how to use zipOrAccumulate to achieve the error accumulation behavior of Validated's zip. This example shows combining results that may contain single errors or NonEmptyList errors. ```kotlin fun one(): Either = "error-1".left() fun two(): Either, Int> = nonEmptyListOf("error-2", "error-3").left() fun example() { either, Int> { zipOrAccumulate( { one().bind() }, { two().bindNel() } ) { x, y -> x + y } } shouldBe nonEmptyListOf("error-1", "error-2", "error-3").left() } ``` -------------------------------- ### Basic Lens Operations: Get, Set, Modify Source: https://arrow-kt.io/learn/immutable-data/lens Demonstrates the fundamental lens operations: `get` to retrieve a value, `set` to update it, and `modify` to transform it using a function. This snippet showcases these operations on a `Person` object. ```kotlin fun example() { val me = Person( "Alejandro", 35, Address(Street("Kotlinstraat", 1), City("Hilversum", "Netherlands")) ) Person.name.get(me) shouldBe "Alejandro" val meAfterBirthdayParty = Person.age.modify(me) { it + 1 } Person.age.get(meAfterBirthdayParty) shouldBe 36 val newAddress = Address(Street("Kotlinplein", null), City("Amsterdam", "Netherlands")) val meAfterMoving = Person.address.set(me, newAddress) Person.address.get(meAfterMoving) shouldBe newAddress } ``` -------------------------------- ### Constructing Option Values Source: https://arrow-kt.io/learn/typed-errors/wrappers/nullable-and-option Demonstrates the creation of Some and None instances, and their equivalent Option constructions from values and null. ```kotlin val some: Some = Some("I am wrapped in something") val none: None = None val optionA: Option = "I am wrapped in something".some() val optionB: Option = none() fun example() { some shouldBe optionA none shouldBe optionB } ``` -------------------------------- ### Example of Accumulated Validation Errors Source: https://arrow-kt.io/learn/typed-errors/working-with-typed-errors Demonstrates how both validation errors are collected when using accumulation. ```kotlin fun example() { User("", -1) shouldBe Left(nonEmptyListOf(UserProblem.EmptyName, UserProblem.NegativeAge(-1))) } ``` -------------------------------- ### Resource Classes for Demonstration Source: https://arrow-kt.io/learn/coroutines/resource-safety Defines `UserProcessor` and `DataSource` classes to illustrate resource management scenarios. These classes have start/connect and shutdown/close methods. ```kotlin class UserProcessor { fun start(): Unit = println("Creating UserProcessor") fun shutdown(): Unit = println("Shutting down UserProcessor") } class DataSource { fun connect(): Unit = println("Connecting dataSource") fun close(): Unit = println("Closed dataSource") } class Service(val db: DataSource, val userProcessor: UserProcessor) { suspend fun processData(): List = throw RuntimeException("I'm going to leak resources by not closing them") } ``` -------------------------------- ### Define a data class Source: https://arrow-kt.io/learn/immutable-data/reflection Example of a data class definition used for reflection-based optics. ```kotlin data class Person(val name: String, val friends: List) ``` -------------------------------- ### Single-Line Sequential Composition with Raise DSL Source: https://arrow-kt.io/learn/typed-errors/from-either-to-raise Shows a more concise single-line implementation of sequential composition using the Raise DSL, demonstrating the flexibility of the 'bind' function. ```kotlin fun foo(n: Int): Either = either { g(f(n).bind()).bind().summarize() } ``` -------------------------------- ### Using onState Helpers for ProgressiveOutcome Source: https://arrow-kt.io/learn/typed-errors/wrappers/outcome-progress Illustrates using helper functions like onSuccess and onLoading to react to specific states of a ProgressiveOutcome, useful for UI updates. ```kotlin fun printProgress(po: ProgressiveOutcome) { po.onSuccess { println("current value is $it") } po.onLoading { println("loading...") } } ``` -------------------------------- ### Example of deprecated Ior crosswalk usage Source: https://arrow-kt.io/learn/quickstart/migration Demonstrates how the deprecated crosswalk method is used with an Ior.Right value. ```kotlin fun deprecatedCrosswalk() { val rightIor: Ior = Ior.Right(124) val result = rightIor.crosswalk { listOf(it) } result shouldBe listOf(Ior.Right(124)) } ``` -------------------------------- ### Nullability flatMap implementation Source: https://arrow-kt.io/learn/design/receivers-flatmap An example of a flatMap implementation for nullable types in Kotlin. It short-circuits if the receiver is null. ```kotlin fun A?.flatMap(next: (A) -> B?): B? = when (this) { null -> null else -> next(this) } ``` -------------------------------- ### Migrating replicate with Manual Initial Value Source: https://arrow-kt.io/learn/quickstart/migration Illustrates the manual addition of the initial value '0' to successfully migrate the replicate function for Either. ```kotlin // Adding the empty value to complete the replacement of the deprecated method fun migrateReplicate() { val rEither: Either = 125.right() val n = 3 val res = if (n <= 0) Either.Right(0) else rEither.map { b -> List(n) { b }.fold(0) { r, t -> r + t } } res shouldBe Either.Right(375) } ``` -------------------------------- ### Accumulating Errors with Either and DialogResult Source: https://arrow-kt.io/learn/typed-errors/wrappers/own-error-types Example of accumulating errors using mapOrAccumulate with a function that returns DialogResult, then converting to Either. ```kotlin fun dialog(int: Int): DialogResult = if(int % 2 == 0) DialogResult.Positive(it) else Dialog.Neutral val res: Either, NonEmptyList> = listOf(1, 2, 3).mapOrAccumulate { i: Int -> dialog(it).getOrElse { raise(it) } } dialogResult { res.mapLeft { ... }.bind() } ``` -------------------------------- ### Migrating combineAll with Manual Initial Value Source: https://arrow-kt.io/learn/quickstart/migration Illustrates the manual addition of the initial value '0' to successfully migrate the combineAll function. ```kotlin // Adding the initial value to complete the replacement of the deprecated method fun migrateCombineAll() { val l: List = listOf(1, 2, 3, 4, 5) l.fold(0) { a1, a2 -> a1 + a2 } shouldBe 10 } ``` -------------------------------- ### Use Version Catalog Dependencies (Amper) Source: https://arrow-kt.io/learn/quickstart/setup Reference Arrow libraries using the version catalog in your Amper build file. ```yaml dependencies: - $libs.arrow.core - $libs.arrow.fx.coroutines ``` -------------------------------- ### Use Version Catalog Dependencies (Gradle Kotlin) Source: https://arrow-kt.io/learn/quickstart/setup Reference Arrow libraries using the version catalog in your build.gradle.kts file. ```kotlin dependencies { implementation(libs.arrow.core) implementation(libs.arrow.fx.coroutines) } ``` -------------------------------- ### Defining Success Paths Source: https://arrow-kt.io/learn/typed-errors/working-with-typed-errors Illustrates how to define a function that successfully returns a User using both the wrapper type approach with Either and the computation context approach with Raise. ```kotlin object UserNotFound data class User(val id: Long) // wrapper type approach val user: Either = User(1).right() // computation context approach fun Raise.user(): User = User(1) ``` -------------------------------- ### Simple Racing with raceN Source: https://arrow-kt.io/learn/coroutines/racing Demonstrates racing two download operations from different servers using `raceN`. The first successful download wins, and the result is merged. This pattern is useful when you need a value from one of multiple sources and don't care which one succeeds first. ```kotlin suspend fun file(server1: String, server2: String) = raceN( { downloadFrom(server1) }, { downloadFrom(server2) } ).merge() ``` -------------------------------- ### Native Target Configuration (Windows) Source: https://arrow-kt.io/learn/coroutines/suspendapp Configures a Kotlin Multiplatform project to build an executable for the Windows native target. ```kotlin mingwX64 { binaries.executable() } ``` -------------------------------- ### Define Resources as Resource Values Source: https://arrow-kt.io/learn/coroutines/resource-safety Defines resources as `Resource` values, which are recipes for acquisition and release. These are later bound within a `resourceScope`. Shows how to handle release with `ExitCase` and use `Dispatchers.IO`. ```kotlin val userProcessor: Resource = resource({ UserProcessor().also { it.start() } }) { p, _ -> p.shutdown() } val dataSource: Resource = resource({ DataSource().also { it.connect() } }) { ds, exitCase -> println("Releasing $ds with exit: $exitCase") withContext(Dispatchers.IO) { ds.close() } } val service: Resource = resource { Service(dataSource.bind(), userProcessor.bind()) } suspend fun example(): Unit = resourceScope { val data = service.bind().processData() println(data) } ``` -------------------------------- ### Create a Prism for a specific subclass Source: https://arrow-kt.io/learn/immutable-data/reflection Demonstrates creating a prism focused on a specific subclass (Fork) of a sealed interface (Cutlery) using the 'instance' method. ```kotlin instance() ``` -------------------------------- ### Migrate Zip to Bind in DSL Source: https://arrow-kt.io/learn/quickstart/migration Shows how to replace the deprecated `zip` function with the `bind` method within an `either` DSL block. This is useful for combining results from multiple effectful computations. ```kotlin fun one(): Either = Either.Right(1) // val old: Either = one().zip(one()) { x, y -> x + y } val new: Either = either { one().bind() + one().bind() } ``` -------------------------------- ### Exponential Backoff Policy Source: https://arrow-kt.io/learn/resilience/retry-and-repeat Constructs a schedule using exponential backoff, starting with a 250ms delay. This is ideal for retrying network requests where delays should increase with each attempt. ```kotlin @ExperimentalTime val exponential = Schedule.exponential(250.milliseconds) ``` -------------------------------- ### Traverse to mapOrAccumulate Example Source: https://arrow-kt.io/learn/quickstart/migration Demonstrates how to use mapOrAccumulate to replicate the error accumulation behavior of Validated's traverse. It shows handling single errors and NonEmptyList errors. ```kotlin fun one(): Either = "error-1".left() fun two(): Either, Int> = nonEmptyListOf("error-2", "error-3").left() fun example() { listOf(1, 2).mapOrAccumulate { one().bind() } shouldBe nonEmptyListOf("error-1", "error-1").left() listOf(1, 2).mapOrAccumulate { two().bind() } shouldBe nonEmptyListOf("error-2", "error-3", "error-2", "error-3").left() } ``` -------------------------------- ### Function with Logging Side Effect Source: https://arrow-kt.io/learn/design/receivers-flatmap An example of a function that includes a side effect (printing to console) in addition to its primary computation. This behavior is not apparent from its return type alone. ```kotlin fun loggingAdd(x: Int, y: Int): Int { println("x = $x, y = $y") return x + y } ``` -------------------------------- ### Migrating zip with Manual '+' Operation Source: https://arrow-kt.io/learn/quickstart/migration Illustrates the manual addition of the '+' operation for Long? to successfully migrate the zip method. ```kotlin fun migrateZip() { val validated: Validated = 3.valid() val res = Either.zipOrAccumulate( { e1, e2 -> nullable { e1.bind() + e2.bind() } }, validated.toEither(), Valid(Unit).toEither() ) { a, _ -> a }.toValidated() res shouldBe Validated.Valid(3) } ``` -------------------------------- ### Native Target Configuration (Linux) Source: https://arrow-kt.io/learn/coroutines/suspendapp Configures a Kotlin Multiplatform project to build an executable for the Linux native target. ```kotlin linuxX64 { binaries.executable() } ``` -------------------------------- ### Creating a Collector for Average Source: https://arrow-kt.io/learn/collections-functions/collectors This snippet shows how to define a collector for calculating the average using `zip` to combine sum and length collectors. ```kotlin import arrow.collectors.Collectors import arrow.collectors.collect import arrow.collectors.zip fun divide(x: Int, y: Int): Double = x.toDouble() / y.toDouble() val averageCollector = zip(Collectors.sum, Collectors.length, ::divide) ``` -------------------------------- ### Attempting to Set a Non-Existent Value with Index Source: https://arrow-kt.io/learn/immutable-data/optional Illustrates that using `set` with an `index` optional on a non-existent key does not add the element to the map. The example verifies that the key is not present after the operation. ```kotlin fun example() { val dbWithJack = Db.cities.index("Jack").set(db, City("London", "UK")) // Jack was not really added to the database ("Jack" in dbWithJack.cities) shouldBe false } ``` -------------------------------- ### Ktor Jackson Serialization with Arrow Module Source: https://arrow-kt.io/learn/integrations Configure Jackson for Ktor to support Arrow types by registering a custom ObjectMapper with the ArrowModule. This setup handles Arrow-specific serialization needs. ```kotlin object JsonMapper { val mapper: ObjectMapper = ObjectMapper() .registerModule(KotlinModule(singletonSupport = SingletonSupport.CANONICALIZE)) .registerArrowModule() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION) .setSerializationInclusion(JsonInclude.Include.NON_ABSENT) } install(ContentNegotiation) { register(ContentType.Application.Json, JacksonConverter(JsonMapper.mapper)) } ``` -------------------------------- ### Database Implementation from Connection Source: https://arrow-kt.io/learn/design/effects-contexts Provides an implementation of the Database interface by wrapping an existing DatabaseConnection. ```kotlin class DatabaseFromConnection(conn: DatabaseConnection) : Database { override suspend fun execute(q: Query): Result = conn.execute(q) } ``` -------------------------------- ### Native Target Configuration (macOS x64) Source: https://arrow-kt.io/learn/coroutines/suspendapp Configures a Kotlin Multiplatform project to build an executable for the macOS x64 native target. ```kotlin macosX64 { binaries.executable() } ``` -------------------------------- ### Update MutableState with Arrow-Optics Compose Source: https://arrow-kt.io/learn/immutable-data/lens This example shows how to use the `updateCopy` function from `arrow-optics-compose` to atomically update a `MutableState` within a ViewModel. It's useful for applying multiple modifications to the previous state. ```kotlin class AppViewModel: ViewModel() { private val _personData = mutableStateOf(...) fun updatePersonalData( newName: String, newAge: Int ) { _personData.updateCopy { Person.name set newName Person.age set newAge } } } ``` -------------------------------- ### Sequential Composition with Raise DSL Source: https://arrow-kt.io/learn/typed-errors/from-either-to-raise Translates the Either.flatMap/map pattern into the Raise DSL using the 'either' builder and 'bind'. This offers a more sequential and readable style. ```kotlin fun foo(n: Int): Either = either { val s = f(n).bind() val t = g(s).bind() t.summarize() } ``` -------------------------------- ### Explicitly Typed Function with Context Receivers Source: https://arrow-kt.io/learn/design/receivers-flatmap An example showcasing how context receivers can make side effects like error raising and random number generation explicit in a function's type signature. ```kotlin context(Raise, Random) fun crazyAdd(x: Int, y: Int): Int ``` -------------------------------- ### Using Context Receivers with `with` Source: https://arrow-kt.io/learn/design/receivers-flatmap Demonstrates how to provide an implementation for a context receiver using the `with` function. This injects the `DbUserRepository` into the scope. ```kotlin fun example() { createDbConnection().use { db -> with(DbUserRepository(db)) { println(getUserName(UserId(1))) } } } ``` -------------------------------- ### Node.js Target Configuration Source: https://arrow-kt.io/learn/coroutines/suspendapp Configures a Kotlin Multiplatform project to build an executable for the Node.js target. ```kotlin js(IR) { nodejs { binaries.executable() } } ``` -------------------------------- ### Primitive Type-Based Event Model Source: https://arrow-kt.io/learn/design/domain-modeling An example of a basic data class using primitive types. This model is prone to errors as different fields can share the same type, leading to potential bugs that the compiler cannot detect. ```kotlin data class Event( val id: Long, val title: String, val organizer: String, val description: String, val date: LocalDate ) ``` -------------------------------- ### Custom Exception Handling in Racing Source: https://arrow-kt.io/learn/coroutines/racing Illustrates how to install a custom `CoroutineExceptionHandler` within a `withContext` block to manage exceptions occurring during a race. This allows for specific error handling logic, such as printing stack traces. ```kotlin suspend fun customErrorHandling(): String = withContext(CoroutineExceptionHandler { ctx, t -> t.printStackTrace() }) { racing { race { delay(2.seconds) throw RuntimeException("boom!") } race { delay(10.seconds) "Winner!" } } } ``` -------------------------------- ### Include Arrow BOM (Gradle Kotlin) Source: https://arrow-kt.io/learn/quickstart/setup Use the Arrow Bill-of-Materials to manage versions for all Arrow dependencies in your build.gradle.kts. ```kotlin dependencies { implementation(platform("io.arrow-kt:arrow-stack:2.2.3")) implementation("io.arrow-kt:arrow-core") implementation("io.arrow-kt:arrow-fx-coroutines") } ``` -------------------------------- ### Using Raise with Stratified DialogResult Source: https://arrow-kt.io/learn/typed-errors/wrappers/own-error-types Demonstrates how to use the Raise DSL with a stratified DialogResult, binding values and errors. ```kotlin dialogResult { val x: DialogResult.Positive(1).bind() val y: Int = DialogResult.Error.left().bind() x + y } ``` -------------------------------- ### Include Arrow BOM (Gradle Groovy) Source: https://arrow-kt.io/learn/quickstart/setup Use the Arrow Bill-of-Materials to manage versions for all Arrow dependencies in your build.gradle. ```groovy dependencies { implementation platform('io.arrow-kt:arrow-stack:2.2.3') implementation 'io.arrow-kt:arrow-core' implementation 'io.arrow-kt:arrow-fx-coroutines' } ``` -------------------------------- ### firstOrElse function demonstrating nested nullability issue Source: https://arrow-kt.io/learn/typed-errors/wrappers/nullable-and-option This example shows the unexpected behavior of the basic `firstOrElse` function when the list's first element is `null`. It incorrectly returns the default value instead of `null`. ```kotlin fun example() { listOf(null, 2, 3).firstOrElse { -1 } shouldBe null } ``` -------------------------------- ### Include Arrow Dependencies (Amper) Source: https://arrow-kt.io/learn/quickstart/setup List Arrow core and fx-coroutines dependencies in your Amper build file. ```yaml dependencies: - io.arrow-kt:arrow-core:2.2.3 - io.arrow-kt:arrow-fx-coroutines:2.2.3 ``` -------------------------------- ### Lens Composition for Nested Access Source: https://arrow-kt.io/learn/immutable-data/lens Illustrates how to compose lenses to access deeply nested values within a data structure. This example creates a lens to directly access the city name of a person's address. ```kotlin val personCity: Lens = Person.address compose Address.city compose City.name fun example() { val me = Person( "Alejandro", 35, Address(Street("Kotlinstraat", 1), City("Hilversum", "Netherlands")) ) personCity.get(me) shouldBe "Hilversum" val meAtTheCapital = personCity.set(me, "Amsterdam") } ``` -------------------------------- ### Idiomatic Error Raising with `ensure` Source: https://arrow-kt.io/learn/typed-errors/from-either-to-raise This is the more idiomatic way to write the previous example using the `ensure` function. It checks a condition and raises a specific error if the condition is false, providing a cleaner syntax for conditional error signaling. ```kotlin fun fooThatRaises(n: Int): Either = either { ensure(n >= 0) { Error.NegativeInput } val s = f(n).bind() val t = g(s).bind() t.summarize() } ``` -------------------------------- ### Insert User with Raise and Catch Source: https://arrow-kt.io/learn/typed-errors/working-with-typed-errors This snippet demonstrates wrapping a database insertion with `catch` to handle `SQLException`. It specifically transforms unique violation errors into a `UserAlreadyExists` typed error using the `Raise` DSL. ```kotlin data class UserAlreadyExists(val username: String, val email: String) // computation context approach suspend fun Raise.insertUser(username: String, email: String): Long = catch({ UsersQueries.insert(username, email) }) { e: SQLException -> if (e.isUniqueViolation()) raise(UserAlreadyExists(username, email)) else throw e } ``` -------------------------------- ### Enable Maven Central Repository (Gradle Kotlin) Source: https://arrow-kt.io/learn/quickstart/setup Add this to your build.gradle.kts file to enable the Maven Central repository for dependency resolution. ```kotlin repositories { mavenCentral() } ``` -------------------------------- ### Applying a Collector to a List Source: https://arrow-kt.io/learn/collections-functions/collectors This shows how to apply a pre-defined collector to a list to perform the aggregation. ```kotlin val average = list.collect(averageCollector) ``` -------------------------------- ### Context Receiver for Resource and User Repository Source: https://arrow-kt.io/learn/design/receivers-flatmap Demonstrates how to use context receivers to combine different scopes, such as UserRepository and ResourceScope, within a function signature. This allows for composable effects in Kotlin. ```kotlin context(UserRepository, ResourceScope) fun whoKnowsWhatItDoes(name: String) ``` -------------------------------- ### Version Catalog TOML Configuration Source: https://arrow-kt.io/learn/quickstart/setup Define Arrow versions and libraries in your libs.version.toml file for centralized management. ```toml [versions] arrow = "2.2.3" [libraries] arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" } arrow-fx-coroutines = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" } ``` -------------------------------- ### Native Target Configuration (macOS ARM) Source: https://arrow-kt.io/learn/coroutines/suspendapp Configures a Kotlin Multiplatform project to build an executable for the macOS ARM native target. ```kotlin macosArm64 { binaries.executable() } ```