### Shopping Cart Example with Option Do Notation Source: https://context7.com/sandromaglione/fpdart/llms.txt A practical example demonstrating Do notation with Option for a shopping scenario. It chains operations like going to a market and buying items, using `alt` for fallback options and `getOrElse` for a default value if any step fails. This simplifies complex conditional logic. ```dart import 'package:fpdart/fpdart.dart'; // Real-world example: Shopping cart Option goShopping() => Option.Do(($) { final market = $(goToShoppingCenter().alt(goToLocalMarket)); final banana = $(market.buyBanana()); final apple = $(market.buyApple()); final pear = $(market.buyPear()); return 'Shopping: $banana, $apple, $pear'; }).getOrElse(() => 'Could not buy anything'); ``` -------------------------------- ### Option Do Notation Example Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates using Do notation with the Option type to chain operations and extract values. It shows how a `none` value can short-circuit the computation, returning `None` immediately. This simplifies nested `flatMap` calls. ```dart import 'package:fpdart/fpdart.dart'; // Option Do notation Option calculateOption() => Option.Do(($) { final a = $(some(10)); // Extract 10 from Some(10) final b = $(some(20)); // Extract 20 from Some(20) final c = $(none()); // Short-circuits! Returns None return a + b + c; // Never reached }); // Result: None Option successfulOption() => Option.Do(($) { final name = $(some('John')); final age = $(some(30)); return '$name is $age years old'; }); // Result: Some('John is 30 years old') ``` -------------------------------- ### Either Do Notation Example Source: https://context7.com/sandromaglione/fpdart/llms.txt Illustrates Do notation with the Either type for handling computations that can fail. It showcases how a `left` value (representing an error) will short-circuit the computation, returning the `Left` value. This avoids deeply nested error handling. ```dart import 'package:fpdart/fpdart.dart'; // Either Do notation Either calculateEither() => Either.Do(($) { final a = $(right(10)); final b = $(right(20)); final c = $(left('Error!')); // Short-circuits! return a + b + c; }); // Result: Left('Error!') Either divide(int a, int b) => b == 0 ? left('Division by zero') : right(a / b); Either complexCalculation() => Either.Do(($) { final x = $(divide(100, 5)); // 20.0 final y = $(divide(50, 2)); // 25.0 final z = $(divide(30, 3)); // 10.0 return x + y + z; // 55.0 }); // Result: Right(55.0) ``` -------------------------------- ### fpdart State Type: Bank Account Example Source: https://context7.com/sandromaglione/fpdart/llms.txt Illustrates a practical application of the State Type with a bank account example. It shows how to model deposits and withdrawals, handling potential errors like insufficient funds, and composing these operations into a transaction. ```dart import 'package:fpdart/fpdart.dart'; // Bank account example class Account { final String name; final double balance; Account(this.name, this.balance); Account copyWith({String? name, double? balance}) => Account(name ?? this.name, balance ?? this.balance); } State deposit(double amount) => State((acc) => (acc.balance + amount, acc.copyWith(balance: acc.balance + amount)) ); State> withdraw(double amount) => State((acc) { if (acc.balance < amount) { return (left('Insufficient funds'), acc); } return (right(acc.balance - amount), acc.copyWith(balance: acc.balance - amount)); }); final transaction = deposit(100) .flatMap((_) => withdraw(30)) .flatMap((_) => deposit(50)); final account = Account('John', 100); transaction.execute(account).balance; // 220 ``` -------------------------------- ### Install fpdart Dependency in pubspec.yaml Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/README.md This snippet shows how to add the fpdart library as a dependency in your Dart or Flutter project's pubspec.yaml file. Ensure you are using a compatible version. ```yaml # pubspec.yaml dependencies: fpdart: ^1.2.0 ``` -------------------------------- ### fpdart Eq Type Class Examples Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates the usage of the Eq type class in fpdart for equality comparisons. Includes built-in instances for primitive types, creating custom Eq instances for user-defined types, deriving instances using contramap, and combining instances with logical AND. ```dart import 'package:fpdart/fpdart.dart'; // Built-in Eq instances Eq.eqInt.eqv(1, 1); Eq.eqString.eqv('a', 'b'); Eq.eqBool.eqv(true, true); Eq.eqDouble.eqv(1.0, 1.0); // Create custom Eq class User { final int id; final String name; User(this.id, this.name); } final eqUserById = Eq.instance((u1, u2) => u1.id == u2.id); eqUserById.eqv(User(1, 'Alice'), User(1, 'Bob')); // Eq.by - derive Eq from existing one final eqUserByName = Eq.eqString.contramap((u) => u.name); eqUserByName.eqv(User(1, 'Alice'), User(2, 'Alice')); // Combine Eq with and/or final eqBoth = eqUserById.and(eqUserByName); eqBoth.eqv(User(1, 'Alice'), User(1, 'Alice')); eqBoth.eqv(User(1, 'Alice'), User(1, 'Bob')); // DateTime Eq instances Eq.dateEqYear.eqv(DateTime(2023, 6, 15), DateTime(2023, 12, 1)); Eq.dateEqMonth.eqv(DateTime(2023, 6, 15), DateTime(2023, 6, 1)); Eq.dateEqDay.eqv(DateTime(2023, 6, 15), DateTime(2023, 6, 15)); ``` -------------------------------- ### fpdart Order Type Class Examples Source: https://context7.com/sandromaglione/fpdart/llms.txt Illustrates the use of the Order type class in fpdart for ordering comparisons. Covers built-in instances for numeric and date types, creating custom Order instances, deriving instances using contramap, reversing order, and using Order for sorting and finding min/max elements. ```dart import 'package:fpdart/fpdart.dart'; // Built-in Order instances Order.orderInt.compare(1, 2); Order.orderInt.compare(2, 2); Order.orderInt.compare(3, 2); Order.orderDouble.compare(1.5, 2.5); Order.orderNum.compare(1, 2.5); // DateTime ordering Order.orderDate.compare( DateTime(2023, 1, 1), DateTime(2024, 1, 1), ); // Create custom Order final orderUserByAge = Order.from((u1, u2) => u1.id.compareTo(u2.id)); // Order.by - derive Order from existing one final orderUserById = Order.orderInt.contramap((u) => u.id); // Reverse order final descendingInt = Order.orderInt.reverse; descendingInt.compare(1, 2); // between and clamp Order.orderInt.between(5, 1, 10); Order.orderInt.clamp(15, 1, 10); Order.orderInt.clamp(-5, 1, 10); // Use with sorting final numbers = [3, 1, 4, 1, 5]; numbers.sortBy(Order.orderInt); numbers.sortBy(Order.orderInt.reverse); // Use with min/max numbers.minimumBy(Order.orderInt); numbers.maximumBy(Order.orderInt); ``` -------------------------------- ### Task Do Notation for Async Computations Source: https://context7.com/sandromaglione/fpdart/llms.txt Shows how to use Do notation with the Task type for asynchronous computations. It allows chaining `await` operations within a `Task.Do` block, simplifying the composition of multiple asynchronous steps into a single `Task`. The example demonstrates delaying execution and combining results. ```dart import 'package:fpdart/fpdart.dart'; // Task Do notation Task asyncCalculation() => Task.Do(($) async { final a = await $(Task.of(10)); final b = await $(Task(() async => 20)); final c = await $(Task(() async { await Future.delayed(Duration(milliseconds: 100)); return 30; })); return a + b + c; }); // Result: 60 ``` -------------------------------- ### fpdart State Type: Basic Operations Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates the fundamental operations of the State Type in fpdart, including creating stateful computations, running them to get both the value and the new state, evaluating to get only the value, and executing to get only the new state. ```dart import 'package:fpdart/fpdart.dart'; // State - S is state type, A is return value type // Simple counter example final State increment = State((count) => ('Incremented', count + 1)); final State decrement = State((count) => ('Decremented', count - 1)); // Run returns both value and new state final (value, newState) = increment.run(0); // value: 'Incremented', newState: 1 // evaluate() gets just the value final justValue = increment.evaluate(0); // 'Incremented' // execute() gets just the state final justState = increment.execute(0); // 1 ``` -------------------------------- ### fpdart Do Notation for Chaining Functions Source: https://github.com/sandromaglione/fpdart/blob/main/README.md Demonstrates how to use fpdart's Do notation to simplify chaining of Option-returning functions, making code more linear and readable compared to traditional flatMap usage. It requires the fpdart package. ```dart /// Without the Do notation String goShopping() => goToShoppingCenter() .alt(goToLocalMarket) .flatMap( (market) => market.buyBanana().flatMap( (banana) => market.buyApple().flatMap( (apple) => market.buyPear().flatMap( (pear) => Option.of('Shopping: $banana, $apple, $pear') ) ) ) ) .getOrElse( () => 'I did not find 🍌 or 🍎 or 🍐, so I did not buy anything 🤷‍♂️' ); /// Using the Do notation String goShoppingDo() => Option.Do( ($) { final market = $(goToShoppingCenter().alt(goToLocalMarket)); final amount = $(market.buyAmount()); final banana = $(market.buyBanana()); final apple = $(market.buyApple()); final pear = $(market.buyPear()); return 'Shopping: $banana, $apple, $pear'; }, ).getOrElse( () => 'I did not find 🍌 or 🍎 or 🍐, so I did not buy anything 🤷‍♂️' ); ``` -------------------------------- ### fpdart State Type: State Access and Modification Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates methods for interacting with the current state within a State computation. `get()` retrieves the entire state, `gets()` extracts a specific value from the state, `put()` sets a new state, and `modify()` transforms the existing state. ```dart import 'package:fpdart/fpdart.dart'; // get() reads current state final readState = State((s) => (s, s)).get(); readState.run(42); // (42, 42) // gets() extracts value from state final getSquare = State((s) => (s, s)).gets((s) => s * s); getSquare.evaluate(5); // 25 // put() sets new state final setState = State((s) => (unit, s)).put(100); setState.execute(0); // 100 // modify() transforms state final doubleState = State((s) => (unit, s)).modify((s) => s * 2); doubleState.execute(5); // 10 ``` -------------------------------- ### Lifting IO to Task with FlatMap Source: https://context7.com/sandromaglione/fpdart/llms.txt Shows how to lift a synchronous `IO` computation into an asynchronous `Task` using `flatMapTask`. This is useful when you need to perform asynchronous operations based on the result of a synchronous `IO` computation, allowing seamless integration between sync and async code. ```dart import 'package:fpdart/fpdart.dart'; // FlatMap to Task (lift sync to async) final asyncResult = io.flatMapTask((value) => Task(() async { await Future.delayed(Duration(seconds: 1)); return value * 2; })); await asyncResult.run(); // 84 ``` -------------------------------- ### fpdart Do Notation vs. Standard Chaining in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/README.md Demonstrates how to chain operations using fpdart's Do notation for improved readability compared to traditional flatMap chaining. The Do notation simplifies the extraction of values from Options. ```dart /// Without the Do notation String goShopping() => goToShoppingCenter() .alt(goToLocalMarket) .flatMap( (market) => market.buyBanana().flatMap( (banana) => market.buyApple().flatMap( (apple) => market.buyPear().flatMap( (pear) => Option.of('Shopping: $banana, $apple, $pear'), ), ), ), ) .getOrElse( () => 'I did not find 🍌 or 🍎 or 🍐, so I did not buy anything 🤷‍♂️', ); /// Using the Do notation String goShoppingDo() => Option.Do( ($) { final market = $(goToShoppingCenter().alt(goToLocalMarket)); final amount = $(market.buyAmount()); final banana = $(market.buyBanana()); final apple = $(market.buyApple()); final pear = $(market.buyPear()); return 'Shopping: $banana, $apple, $pear'; }, ).getOrElse( () => 'I did not find 🍌 or 🍎 or 🍐, so I did not buy anything 🤷‍♂️', ); ``` -------------------------------- ### Option Constructors in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/example/src/option/cheat_sheet.md Demonstrates how to create Option instances using `some`, `none`, `Option.of`, and `Option.fromNullable`. These constructors are used to represent the presence or absence of a value, with `Option.fromNullable` handling null values. ```dart import 'package:fpdart/fpdart.dart'; // Representing a value final someValue = option(10); final someValue2 = Option.of(10); // Representing no value final noneValue = none(); final noneValue2 = Option.none(); // Handling nullable values final fromNullableWithValue = Option.fromNullable(10); final fromNullableWithoutValue = Option.fromNullable(null); print(someValue); // Some(10) print(noneValue); // None() print(fromNullableWithValue); // Some(10) print(fromNullableWithoutValue); // None() ``` -------------------------------- ### IO Type: Composing Synchronous Dart Functions Source: https://github.com/sandromaglione/fpdart/blob/main/README.md Explains the IO type for wrapping synchronous functions that do not fail. Demonstrates creating IO instances, mapping, running, and chaining computations. ```dart /// Create instance of [IO] from a value final IO io = IO.of(10); /// Create instance of [IO] from a sync function final ioRun = IO(() => 10); /// Map [int] to [String] final IO map = io.map((a) => '$a'); /// Extract the value inside [IO] by running its function final int value = io.run(); /// Chain another [IO] based on the value of the current [IO] final flatMap = io.flatMap((a) => IO.of(a + 10)); ``` -------------------------------- ### fpdart State Type: Stack Operations Source: https://context7.com/sandromaglione/fpdart/llms.txt Provides examples of using the State Type to manage a stack data structure. It includes functions for pushing, popping, and peeking elements, as well as composing these operations using `State.Do` notation. ```dart import 'package:fpdart/fpdart.dart'; // Stack example typedef Stack = List; State, Unit> push(int value) => State((stack) => (unit, [...stack, value]) ); State, Option> pop() => State((stack) { if (stack.isEmpty) return (none(), stack); return (some(stack.last), stack.sublist(0, stack.length - 1)); }); State, int> peek() => State((stack) => (stack.isEmpty ? -1 : stack.last, stack) ); // Compose stack operations final stackOps = State, String>.Do(($) { $(push(10)); $(push(20)); $(push(30)); final top = $(pop()); // Some(30) return 'Popped: ${top.getOrElse(() => -1)}'; }); final (result, finalStack) = stackOps.run([]); // result: 'Popped: 30', finalStack: [10, 20] ``` -------------------------------- ### Creating and Running IO Values in Dart Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates the creation of `IO` values in Dart, which represent synchronous side-effectful computations. It shows how to create `IO` instances for values and side effects, and how `run()` is used to execute these computations. `IO.of` provides a simple way to wrap pure values. ```dart import 'package:fpdart/fpdart.dart'; // Creating IO values final IO io = IO(() => 42); final IO immediate = IO.of('hello'); // IO for side effects final IO getTime = IO(() => DateTime.now()); final IO printMessage = IO(() => print('Hello!')); // Execute the IO final result = io.run(); // 42 ``` -------------------------------- ### TaskEither Do Notation for Async Operations Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates the use of Do notation with TaskEither for asynchronous operations that can fail. It shows how `await $(...)` is used to extract results from `TaskEither` computations, and how `left` can be used to short-circuit on errors. This simplifies complex async workflows. ```dart import 'package:fpdart/fpdart.dart'; // TaskEither Do notation (async) TaskEither processOrder(int userId, int productId) => TaskEither.Do(($) async { final user = await $(fetchUser(userId)); final product = await $(fetchProduct(productId)); final inventory = await $(checkInventory(productId)); if (inventory.quantity < 1) { // Use left to short-circuit return await $(TaskEither.left('Out of stock')); } final order = await $(createOrder(user, product)); await $(sendConfirmation(user.email, order)); return order; }); ``` -------------------------------- ### Option tryCatch in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/example/src/option/cheat_sheet.md Illustrates creating an Option from a function that might throw an exception using `Option.tryCatch`. If the function executes successfully, its result is wrapped in `Some`; otherwise, `None` is returned. ```dart import 'package:fpdart/fpdart.dart'; // Function that succeeds final optionSuccess = Option.tryCatch(() => 10 * 2); // Function that throws an exception final optionFailure = Option.tryCatch(() => throw Exception('Something went wrong')); print(optionSuccess); // Some(20) print(optionFailure); // None() ``` -------------------------------- ### Option flatMap method in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/example/src/option/cheat_sheet.md Demonstrates `flatMap`, similar to `andThen`, used for chaining operations that return an Option. It applies a function to the value within `Some` and returns the resulting Option. If the initial Option is `None`, `None` is returned. ```dart import 'package:fpdart/fpdart.dart'; final initialSome = Option.some(10); final initialNone = none(); // flatMap on Some final flatMapOnSome = initialSome.flatMap((value) => Option.some(value + 5)); // flatMap on None final flatMapOnNone = initialNone.flatMap((value) => Option.some(value + 5)); // Chaining flatMap final chainedFlatMap = initialSome.flatMap((v1) => Option.some(v1 * 2)).flatMap((v2) => Option.some(v2 - 3)); // flatMap with a None result final flatMapToNone = initialSome.flatMap((value) => Option.none()); print(flatMapOnSome); // Some(15) print(flatMapOnNone); // None() print(chainedFlatMap); // Some(17) print(flatMapToNone); // None() ``` -------------------------------- ### fpdart Reader Type: Dependency Injection and Context Management Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates how to use the `Reader` type for dependency injection in Dart. It shows how to define a context (`AppConfig`), create Reader functions that depend on this context, compose them using `Reader.Do`, and run them with an actual configuration. It also illustrates common operations like `map`, `flatMap`, `ask`, `asks`, `local`, and `map2` for transforming and combining Reader computations. ```dart import 'package:fpdart/fpdart.dart'; // Define a configuration/context type class AppConfig { final String apiUrl; final String apiKey; final bool debug; AppConfig({required this.apiUrl, required this.apiKey, this.debug = false}); } // Create Reader functions that depend on config Reader getApiUrl() => Reader((config) => config.apiUrl); Reader getAuthHeader() => Reader((config) => 'Bearer ${config.apiKey}' ); Reader buildEndpoint(String path) => Reader((config) => Uri.parse('${config.apiUrl}/$path') ); // Compose Readers Reader makeRequest(String path) => Reader.Do(($) { final url = $(buildEndpoint(path)); final auth = $(getAuthHeader()); return 'GET $url with $auth'; }); // Run with actual config final config = AppConfig( apiUrl: 'https://api.example.com', apiKey: 'secret-key', ); final result = makeRequest('users').run(config); // 'GET https://api.example.com/users with Bearer secret-key' // Map transforms the result final mapped = getApiUrl().map((url) => url.toUpperCase()); mapped.run(config); // 'HTTPS://API.EXAMPLE.COM' // FlatMap chains operations final chained = getApiUrl().flatMap((url) => Reader((config) => '$url?debug=${config.debug}') ); chained.run(config); // 'https://api.example.com?debug=false' // ask() gets the entire context final askExample = Reader((c) => c) .flatMap((config) => Reader((_) => config.apiUrl)); // asks() extracts specific values final debug = Reader((c) => c).asks((config) => config.debug); // local() transforms the context type class SubConfig { final AppConfig app; final String userId; SubConfig(this.app, this.userId); } final withUserId = getApiUrl().local((sub) => sub.app); final subConfig = SubConfig(config, 'user-123'); withUserId.run(subConfig); // 'https://api.example.com' // Combine multiple Readers final reader1 = Reader((n) => 'Number: $n'); final reader2 = Reader((n) => 'Doubled: ${n * 2}'); final combined = reader1.map2(reader2, (a, b) => '$a, $b'); combined.run(5); // 'Number: 5, Doubled: 10' ``` -------------------------------- ### fpdart Either Type: Creation and Basic Operations Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates how to create Either values using constructors and shorthand methods. It also shows basic mapping operations on Right and Left sides, and bimapping to transform both. ```dart import 'package:fpdart/fpdart.dart'; // Creating Either values final Either success = Either.of(42); // Right(42) final Either failure = Either.left('Error'); // Left('Error') // Shorthand constructors final rightValue = right(42); // Right(42) final leftValue = left('Oops'); // Left('Oops') // Map only affects Right values final mapped = success.map((a) => a * 2); // Right(84) final mappedFail = failure.map((a) => a * 2); // Left('Error') // Map Left values final mappedLeft = failure.mapLeft((e) => 'Wrapped: $e'); // Left('Wrapped: Error') // Bimap - transform both sides final biMapped = success.bimap( (l) => 'Error: $l', // transform Left (r) => r.toString(), // transform Right ); // Right('42') ``` -------------------------------- ### Option fromPredicate in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/example/src/option/cheat_sheet.md Shows how to create an Option based on a predicate function using `Option.fromPredicate`. This method returns `Some` if the predicate returns true for the given value, otherwise `None`. ```dart import 'package:fpdart/fpdart.dart'; final value = 10; // Predicate returns true final optionWithPredicateTrue = Option.fromPredicate(value, (v) => v > 5); // Predicate returns false final optionWithPredicateFalse = Option.fromPredicate(value, (v) => v < 5); print(optionWithPredicateTrue); // Some(10) print(optionWithPredicateFalse); // None() ``` -------------------------------- ### Converting IO to Async Types Source: https://context7.com/sandromaglione/fpdart/llms.txt Illustrates how to convert `IO` computations into asynchronous types like `Task` and `TaskEither`, and `IOOption`. This allows integrating synchronous side effects into asynchronous workflows or handling potential failures explicitly. `toTask` lifts the `IO` to an async context. ```dart import 'package:fpdart/fpdart.dart'; // Convert to async types final task = io.toTask(); // Task final taskEither = io.toTaskEither(); // TaskEither final ioOption = io.toIOOption(); // IOOption ``` -------------------------------- ### Option match method in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/example/src/option/cheat_sheet.md Explains the `match` method for Option, which allows handling both `Some` and `None` cases. It takes two functions: one for the `Some` case and one for the `None` case, returning a value of a common type. ```dart import 'package:fpdart/fpdart.dart'; final someOption = Option.some(10); final noneOption = none(); // Handling Some case final resultFromSome = someOption.match((value) => value * 2, () => 0); // Handling None case final resultFromNone = noneOption.match((value) => value * 2, () => 0); print(resultFromSome); // 20 print(resultFromNone); // 0 ``` -------------------------------- ### Combining and Chaining IO Computations Source: https://context7.com/sandromaglione/fpdart/llms.txt Shows how to combine multiple `IO` computations using `map2` and chain them sequentially using `andThen`. `map2` applies a function to the results of two `IO` computations, while `andThen` executes a second `IO` after the first, ignoring the first's result. This is useful for managing dependent side effects. ```dart import 'package:fpdart/fpdart.dart'; // Combine multiple IOs final io1 = IO.of(10); final io2 = IO.of(20); final combined = io1.map2(io2, (a, b) => a + b); combined.run(); // 30 // Chain ignoring previous result final andThen = io.andThen(() => IO.of('done')); ``` -------------------------------- ### Composing IO Operations with Map and FlatMap Source: https://context7.com/sandromaglione/fpdart/llms.txt Explains how to compose `IO` operations using `map` and `flatMap`. `map` transforms the result of an `IO` computation without changing its structure, while `flatMap` chains `IO` computations, allowing the result of one `IO` to determine the next. This enables building complex side-effectful workflows. ```dart import 'package:fpdart/fpdart.dart'; // Map transforms the result final mapped = getTime.map((dt) => dt.year); // FlatMap chains operations final chained = getTime.flatMap((dt) => IO(() => 'Year: ${dt.year}')); ``` -------------------------------- ### fpdart Either Type: Exception Handling and Nullable Conversions Source: https://context7.com/sandromaglione/fpdart/llms.txt Covers using tryCatch for handling exceptions and converting them into Either. Also shows how to create Either from nullable values and predicates. ```dart import 'package:fpdart/fpdart.dart'; // tryCatch for exception handling final parsed = Either.tryCatch( () => int.parse('invalid'), (error, stack) => 'Parse error: $error', ); // Left('Parse error: FormatException...') // From nullable final fromNull = Either.fromNullable( null, () => 'Value was null', ); // Left('Value was null') // From predicate final validated = Either.fromPredicate( -5, (n) => n > 0, (n) => 'Number must be positive, got $n', ); // Left('Number must be positive, got -5') ``` -------------------------------- ### IO Do Notation for Synchronous Side Effects Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates the use of Do notation with the `IO` type to simplify the composition of synchronous side-effectful computations. It allows extracting values from `IO` instances within a `Do` block, making the code more readable and less verbose than traditional `flatMap` chains. ```dart import 'package:fpdart/fpdart.dart'; // Do notation final calculated = IO.Do(($) { final a = $(IO.of(10)); final b = $(IO.of(20)); return a + b; }); calculated.run(); // 30 ``` -------------------------------- ### Traversing a List with IO Computations Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates how to use `IO.traverseList` to apply an `IO` computation to each element of a list and collect the results. This function transforms a list of values into a single `IO` computation that returns a list of results, useful for batch processing with side effects. ```dart import 'package:fpdart/fpdart.dart'; // Traverse list final ios = [1, 2, 3]; final traversed = IO.traverseList(ios, (n) => IO(() => n * 2)); traversed.run(); // [2, 4, 6] ``` -------------------------------- ### Option alt method in Dart Source: https://github.com/sandromaglione/fpdart/blob/main/packages/fpdart/example/src/option/cheat_sheet.md Shows the `alt` method, which provides an alternative Option if the current Option is `None`. If the current Option is `Some`, it is returned unchanged. Otherwise, the result of the provided function (which returns an Option) is returned. ```dart import 'package:fpdart/fpdart.dart'; final someOption = Option.some(10); final noneOption = none(); // Alt on Some final altOnSome = someOption.alt(() => Option.some(20)); // Alt on None final altOnNone = noneOption.alt(() => Option.some(20)); print(altOnSome); // Some(10) print(altOnNone); // Some(20) ``` -------------------------------- ### Option Type Usage in Dart with Fpdart Source: https://context7.com/sandromaglione/fpdart/llms.txt Demonstrates the creation, transformation, and pattern matching capabilities of the `Option` type in Dart using the fpdart library. It covers handling present and absent values, mapping, flatMapping, and safe operations like `tryCatch`. ```dart import 'package:fpdart/fpdart.dart'; // Creating Option values final Option someValue = Option.of(10); // Some(10) final Option noneValue = Option.none(); // None final Option fromNull = Option.fromNullable(null); // None final Option fromValue = Option.fromNullable(42); // Some(42) // Shorthand constructors final some10 = some(10); // Some(10) final noneInt = none(); // None // Map and flatMap transformations final mapped = someValue.map((a) => a * 2); // Some(20) final flatMapped = someValue.flatMap((a) => a > 5 ? some(a.toString()) : none() ); // Some("10") // Pattern matching final result = someValue.match( () => 'No value', (value) => 'Got: $value', ); // "Got: 10" // Dart 3 pattern matching final message = switch (someValue) { None() => 'Empty', Some(value: final v) => 'Value: $v', }; // "Value: 10" // Extract value with default final valueOrDefault = noneValue.getOrElse(() => -1); // -1 final nullable = someValue.toNullable(); // 10 (or null for None) // Convert to Either final either = noneValue.toEither(() => 'Value is missing'); // Left('Value is missing') // Filter values final filtered = someValue.filter((a) => a > 5); // Some(10) final filteredOut = someValue.filter((a) => a > 100); // None // Safe parsing with tryCatch final parsed = Option.tryCatch(() => int.parse('invalid')); // None final validParse = Option.tryCatch(() => int.parse('42')); // Some(42) // From predicate final conditional = Option.fromPredicate( 10, (value) => value > 5, ); // Some(10) // Traverse and sequence lists final listOfOptions = [some(1), some(2), some(3)]; final optionOfList = Option.sequenceList(listOfOptions); // Some([1, 2, 3]) final mixedList = [some(1), none(), some(3)]; final failedSequence = Option.sequenceList(mixedList); // None ``` -------------------------------- ### fpdart TaskEither: Fallible Asynchronous Operations Source: https://context7.com/sandromaglione/fpdart/llms.txt Illustrates the use of TaskEither for asynchronous operations that can fail. Covers creation from Futures, chaining with flatMap, error handling with mapLeft, pattern matching, and recovery mechanisms. ```dart import 'package:fpdart/fpdart.dart'; import 'package:http/http.dart' as http; // Assuming http package is used // Dummy User and Profile classes for example class User { final int id; final int profileId; const User({required this.id, required this.profileId}); factory User.fromJson(Map json) => User(id: json['id'], profileId: json['profileId']); } class Profile { final String name; final bool verified; const Profile({required this.name, required this.verified}); Profile copyWith({bool? verified}) => Profile(name: name, verified: verified ?? this.verified); } // Creating TaskEither values final TaskEither success = TaskEither.of(42); final TaskEither failure = TaskEither.left('Error'); // From Future with error handling TaskEither fetchUser(int id) => TaskEither.tryCatch( () async { // final response = await http.get(Uri.parse('https://api.example.com/users/$id')); // return User.fromJson(jsonDecode(response.body)); // Dummy implementation for example: if (id == 1) return User(id: id, profileId: 101); throw Exception('User not found'); }, (error, stack) => 'Failed to fetch user: $error', ); // Dummy fetchProfile for example TaskEither fetchProfile(int profileId) => TaskEither.tryCatch( () async { // final response = await http.get(Uri.parse('https://api.example.com/profiles/$profileId')); // return Profile.fromJson(jsonDecode(response.body)); // Dummy implementation for example: if (profileId == 101) return const Profile(name: 'Alice', verified: false); throw Exception('Profile not found'); }, (error, stack) => 'Failed to fetch profile: $error', ); // Chain multiple operations TaskEither getUserProfile(int userId) => fetchUser(userId) .flatMap((user) => fetchProfile(user.profileId)) .map((profile) => profile.copyWith(verified: true)); // Map and mapLeft final mapped = success.map((n) => n.toString()); // TaskEither final leftMapped = failure.mapLeft((e) => Exception(e)); // Pattern matching to Task final task = success.match( (error) => 'Error: $error', (value) => 'Success: $value', ); // await task.run(); // 'Success: 42' // Get value with fallback // final value = await success.getOrElse((l) => -1).run(); // 42 // final fallback = await failure.getOrElse((l) => -1).run(); // -1 // Alternative on failure final withAlt = failure.alt(() => TaskEither.of(0)); // await withAlt.run(); // Right(0) // orElse for recovery final recovered = failure.orElse((error) => TaskEither.of(999)); // await recovered.run(); // Right(999) // Filter with validation final validated = success.filterOrElse( (n) => n > 100, (n) => 'Value $n is too small', ); // await validated.run(); // Left('Value 42 is too small') // Chain Either (sync) with TaskEither (async) Either validateInput(int n) => n > 0 ? right(n) : left('Must be positive'); final chained = success.chainEither((n) => validateInput(n)); // Traverse list with error short-circuit final ids = [1, 2, 3]; final users = TaskEither.traverseList( ids, (id) => fetchUser(id), ); // Returns Right([user1, user2, user3]) or Left on first failure // Sequential traversal (maintains order) final sequentialUsers = TaskEither.traverseListSeq( ids, (id) => fetchUser(id), ); // Delay execution final delayed = success.delay(Duration(seconds: 1)); // Build from nullable final fromNull = TaskEither.fromNullable( null, () => 'Value is null', ); // await fromNull.run(); // Left('Value is null') // From Option final fromOption = TaskEither.fromOption( some(42), () => 'Option was None', ); // await fromOption.run(); // Right(42) // From predicate final fromPred = TaskEither.fromPredicate( 42, (n) => n > 50, (n) => 'Value $n is not greater than 50', ); // await fromPred.run(); // Left('Value 42 is not greater than 50') ``` -------------------------------- ### Load Main Dart JS with Service Worker Fallback (JavaScript) Source: https://github.com/sandromaglione/fpdart/blob/main/examples/pokeapi_functional/web/index.html This JavaScript function handles loading the main Dart JS file for the application. It first checks if a service worker is available and registered. If successful, it loads the main script through the service worker; otherwise, it falls back to a plain script tag. It also includes logic to handle service worker updates and a timeout for fallback. ```javascript var serviceWorkerVersion = null; var scriptLoaded = false; function loadMainDartJs() { if (scriptLoaded) { return; } scriptLoaded = true; var scriptTag = document.createElement('script'); scriptTag.src = 'main.dart.js'; scriptTag.type = 'application/javascript'; document.body.append(scriptTag); } if ('serviceWorker' in navigator) { // Service workers are supported. Use them. window.addEventListener('load', function () { // Wait for registration to finish before dropping the