-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
116 changed files
with
6,615 additions
and
3,665 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import 'package:fpdart/fpdart.dart'; | ||
|
||
void helloWorld(String message) { | ||
print("Hello World: $message"); | ||
} | ||
|
||
/// 1️⃣ Pure function (Thunk) | ||
void Function() helloWorld1(String message) => () { | ||
print("Hello World: $message"); | ||
}; | ||
|
||
/// A thunk with no error is called [IO] in `fpdart` | ||
IO<void> helloWorld1Fpdart(String message) => IO(() { | ||
print("Hello World: $message"); | ||
}); | ||
|
||
/// 2️⃣ Explicit error | ||
/// Understand from the return type if and how the function may fail | ||
Either<Never, void> Function() helloWorld2(String message) => () { | ||
print("Hello World: $message"); | ||
return Either.of(null); | ||
}; | ||
|
||
/// A thunk with explicit error [Either] is called [IOEither] in `fpdart` | ||
IOEither<Never, void> helloWorld2Fpdart1(String message) => IOEither(() { | ||
print("Hello World: $message"); | ||
return Either.of(null); | ||
}); | ||
|
||
/// ...or using the `right` constructor | ||
IOEither<Never, void> helloWorld2Fpdart2(String message) => IOEither.right(() { | ||
print("Hello World: $message"); | ||
}); | ||
|
||
/// 3️⃣ Explicit dependency | ||
/// Provide the `print` method as a dependency instead of implicit global function | ||
abstract class Console { | ||
void log(Object? object); | ||
} | ||
|
||
class ConsoleImpl implements Console { | ||
@override | ||
void log(Object? object) { | ||
print(object); | ||
} | ||
} | ||
|
||
Either<Never, void> Function() Function(Console) helloWorld3(String message) => | ||
(console) => () { | ||
console.log("Hello World: $message"); | ||
return Either.of(null); | ||
}; | ||
|
||
/// Thunk (async) + error + dependency is called [ReaderTaskEither] in `fpdart` | ||
ReaderTaskEither<Console, Never, void> helloWorld3Fpdart(String message) => | ||
ReaderTaskEither((console) async { | ||
console.log("Hello World: $message"); | ||
return Either.of(null); | ||
}); | ||
|
||
void main(List<String> args) { | ||
final definition = helloWorld3("Sandro"); | ||
final thunk = definition(ConsoleImpl()); | ||
thunk(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
void helloWorld(String message) { | ||
print("Hello World: $message"); | ||
} | ||
|
||
void main(List<String> args) { | ||
helloWorld("Sandro"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
name: fpdart_hello_world | ||
publish_to: none | ||
version: 0.1.0 | ||
homepage: https://www.sandromaglione.com/ | ||
repository: https://github.com/SandroMaglione/fpdart | ||
description: Example of Functional programming in Dart and Flutter using fpdart. Write a simple "Hello World" using fpdart. | ||
author: Maglione Sandro <lass.maglio@gmail.com> | ||
|
||
environment: | ||
sdk: ">=3.0.0 <4.0.0" | ||
|
||
dependencies: | ||
fpdart: | ||
path: ../../packages/fpdart | ||
|
||
dev_dependencies: | ||
lint: ^2.1.2 | ||
test: ^1.24.3 | ||
mocktail: ^0.3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import 'package:mocktail/mocktail.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import '../bin/fpdart_hello_world.dart'; | ||
|
||
class ConsoleTest extends Mock implements Console {} | ||
|
||
void main() { | ||
group('helloWorld3Fpdart', () { | ||
test( | ||
'should call "log" from the "Console" dependency with the correct input', | ||
() async { | ||
final console = ConsoleTest(); | ||
const input = "test"; | ||
|
||
when(() => console.log(any)).thenReturn(null); | ||
await helloWorld3Fpdart(input).run(console); | ||
verify(() => console.log("Hello World: $input")).called(1); | ||
}, | ||
); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
group('helloWorld', () { | ||
/// `'should call "print" with the correct input'` | ||
/// | ||
/// This is difficult to test, since `print` is an implicit dependency 🙌 | ||
/// | ||
/// Furthermore, `print` will be executed at every test. Imagine having a | ||
/// request to update a production database instead of `print` (both are side-effects), | ||
/// you do not want to interact with a real database with tests ⚠️ | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,13 @@ | ||
# Managing Imports | ||
|
||
Naming things is hard. Sometimes, the same name gets used for different things. In Dart, naming conflicts can be mitigated through the use of import prefixes, as well as show and hide operations. This is particularly important when using a package like `fpdart` that provides a lot of classes with common names. | ||
Naming things is hard. Sometimes, the same name gets used for different things. In Dart, naming conflicts can be mitigated through the use of [import prefixes](https://dart.dev/language/libraries#specifying-a-library-prefix), as well as [show and hide operations](https://dart.dev/language/libraries#importing-only-part-of-a-library). | ||
|
||
Suppose you decide to use `fpdart` with your Flutter program. You'll quickly discover that `fpdart` uses `State` as a class name, which conflicts with the `State` class in Flutter. | ||
This is particularly important when using a package like `fpdart` that provides a lot of classes with common names. | ||
|
||
That's problem 1. | ||
As an example, suppose you decide to use `fpdart` with your Flutter program. You'll quickly discover that `fpdart` uses `State` as a class name, which conflicts with the `State` class in Flutter. | ||
|
||
Now also suppose you also choose to use `fpdart`'s `Tuple2` class. That's a lot less likely to conflict with anything, but it's still possible. However, you also decide you need a `Tuple3`. `fpdart` doesn't have one. (And likely never will, thanks to the upcoming records feature.) | ||
The solution is to create an import shim that solves both of these problems. We'll call it `functional.dart`. This shim will import `fpdart`, and re-export the classes we want to use. We can rename `fpdart`'s `State` to `FpState` to avoid the conflict. We can then import `functional.dart` instead of `fpdart`. | ||
|
||
However, you found one in the [tuple](https://pub.dev/packages/tuple) package, along with `Tuple4` and `Tuple5`, even though it doesn't have much more than element accessors. Close enough for your application. | ||
`functional.dart` can also hold any other functional programming utilities we want to use. It can also be used to provide or import class extensions and mapping functions between our types and the functional types. | ||
|
||
But now, you decide to import `tuple` as well, and you get a naming conflict for `Tuple2`. | ||
|
||
That's problem 2. | ||
|
||
The solution is to create an import shim that solves both of these problems. We'll call it `functional.dart`. This shim will import `fpdart` and `tuple`, and re-export the classes we want to use. And, we can rename `fpdart`'s `State` to `FpState` to avoid the conflict. We can then import `functional.dart` instead of `fpdart` and `tuple`. | ||
|
||
`functional.dart` can also hold any other functional programming utilities we want to use. It can also be used to provide or import class extensions and mapping functions between our types and the functional types. A one-stop shop for functional programming in Dart! | ||
A one-stop shop for functional programming in Dart! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,17 @@ | ||
import 'package:managing_imports/functional.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main(List<String> arguments) { | ||
// borrow the flatMap test from state_test.dart | ||
void main() { | ||
/// Borrow the `flatMap` test from `state_test.dart` | ||
test('flatMap', () { | ||
final state = FpState<List<int>, int>((s) => Tuple2(s.first, s.sublist(1))); | ||
final state = FpState<List<int>, int>((s) => (s.first, s.sublist(1))); | ||
final ap = state.flatMap<double>( | ||
(a) => FpState( | ||
(s) => Tuple2(a / 2, s.sublist(1)), | ||
(s) => (a / 2, s.sublist(1)), | ||
), | ||
); | ||
final result = ap.run([1, 2, 3, 4, 5]); | ||
expect(result.first, 0.5); | ||
expect(result.second, [3, 4, 5]); | ||
}); | ||
|
||
test('Tuple2', () { | ||
const tuple = Tuple2(1, 2); | ||
// this is the item access syntax for the fpdart package | ||
expect(tuple.first, 1); | ||
expect(tuple.second, 2); | ||
}); | ||
|
||
test('Tuple3', () { | ||
const tuple = Tuple3(1, 2, 3); | ||
// this is the item access syntax for the tuple package | ||
expect(tuple.item1, 1); | ||
expect(tuple.item2, 2); | ||
expect(tuple.item3, 3); | ||
expect(result.$1, 0.5); | ||
expect(result.$2, [3, 4, 5]); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.