-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathoption.dart
113 lines (84 loc) · 2.54 KB
/
option.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
part of "effect.dart";
sealed class Option<R> extends IEffect<Never, Never, R> {
const Option();
factory Option.safeCast(dynamic value) =>
Option.safeCastStrict<R, dynamic>(value);
static Option<R> safeCastStrict<R, V>(V value) {
if (value is R) return Some(value);
return None();
}
factory Option.fromPredicate(R value, bool Function(R r) predicate) {
if (predicate(value)) return Some(value);
return None();
}
factory Option.fromNullable(R? value) {
if (value != null) return Some(value);
return None();
}
factory Option.tryCatch(R Function() f) {
try {
return Some(f());
} catch (_) {
return None();
}
}
R? toNullable();
Option<C> flatMap<C>(Option<C> Function(R r) f);
Option<V> ap<V>(
Option<V Function(R r)> f,
) =>
f.flatMap(
(f) => flatMap(
(v) => Some(f(v)),
),
);
Either<L, R> toEither<L>(L Function() onLeft) => switch (this) {
Some(value: final value) => Right(value),
None() => Left(onLeft()),
};
Option<V> map<V>(V Function(R r) f) => ap(Some(f));
Effect<V, L, R> provide<L, V>(L Function() onNone) => Effect._(
(env) => switch (this) {
None() => Left(Fail(onNone())),
Some(value: final value) => Right(value),
},
);
}
final class Some<R> extends Option<R> {
final R value;
const Some(this.value);
@override
Effect<Never, Never, R> get asEffect => Effect.succeed(value);
@override
Effect<V, L, R> provide<L, V>(L Function() onNone) => Effect.succeed(value);
Option<C> andThen<C>(Option<C> Function() then) => then();
@override
Option<C> flatMap<C>(Option<C> Function(R r) f) => f(value);
@override
R toNullable() => value;
@override
Either<L, R> toEither<L>(L Function() onLeft) => Right(value);
@override
bool operator ==(Object other) => (other is Some) && other.value == value;
@override
int get hashCode => value.hashCode;
@override
String toString() => 'Some($value)';
}
final class None extends Option<Never> {
static const None _none = None._instance();
const None._instance();
factory None() => _none;
@override
@internal
/// **This will always throw, don't use it!**
// ignore: cast_from_null_always_fails
Effect<Never, Never, Never> get asEffect => Effect.fail(null as Never);
Option<C> andThen<C>(Option<C> Function() then) => this;
@override
Option<C> flatMap<C>(Option<C> Function(Never r) f) => this;
@override
Null toNullable() => null;
@override
String toString() => 'None';
}