BadScript 2
Loading...
Searching...
No Matches
Maybe.cs
Go to the documentation of this file.
1//#define CSX_MAYBE_INTERNAL // Uncomment or define at build time set accessibility to internal.
2//#define CSX_REM_EITHER_FUNC // Uncomment or define at build time to remove dependency to Either.cs.
3
4using System;
5using System.Collections.Generic;
6using System.Linq;
7
8namespace CSharpx
9{
10#region Maybe Type
11
15#if !CSX_MAYBE_INTERNAL
16 public
17#endif
18 internal enum MaybeType
19 {
20 Just,
21 Nothing,
22 }
23
29#if !CSX_MAYBE_INTERNAL
30 public
31#endif
32 internal abstract class Maybe<T>
33 {
34 protected Maybe(MaybeType tag)
35 {
36 Tag = tag;
37 }
38
42 public MaybeType Tag { get; }
43
44#region Basic Match Methods
45
49 public bool MatchJust(out T value)
50 {
51 value = Tag == MaybeType.Just ? ((Just<T>)this).Value : default;
52
53 return Tag == MaybeType.Just;
54 }
55
59 public bool MatchNothing()
60 {
61 return Tag == MaybeType.Nothing;
62 }
63
64#endregion
65 }
66
67#endregion
68
72#if !CSX_MAYBE_INTERNAL
73 public
74#endif
75 internal sealed class Nothing<T> : Maybe<T>
76 {
77 internal Nothing()
78 : base(MaybeType.Nothing) { }
79 }
80
84#if !CSX_MAYBE_INTERNAL
85 public
86#endif
87 internal sealed class Just<T> : Maybe<T>
88 {
89 internal Just(T value)
90 : base(MaybeType.Just)
91 {
92 Value = value;
93 }
94
98 public T Value { get; }
99 }
100
104#if !CSX_MAYBE_INTERNAL
105 public
106#endif
107 internal static class Maybe
108 {
109#region Value Case Constructors
110
114 public static Maybe<T> Nothing<T>()
115 {
116 return new Nothing<T>();
117 }
118
122 public static Just<T> Just<T>(T value)
123 {
124 return new Just<T>(value);
125 }
126
127#endregion
128
129#region Monad
130
134 public static Maybe<T> Return<T>(T value)
135 {
136 return Equals(value, default(T)) ? Nothing<T>() : Just(value);
137 }
138
142 public static Maybe<T2> Bind<T1, T2>(Maybe<T1> maybe, Func<T1, Maybe<T2>> func)
143 {
144 T1 value1;
145
146 return maybe.MatchJust(out value1) ? func(value1) : Nothing<T2>();
147 }
148
149#endregion
150
151#region Functor
152
156 public static Maybe<T2> Map<T1, T2>(Maybe<T1> maybe, Func<T1, T2> func)
157 {
158 T1 value1;
159
160 return maybe.MatchJust(out value1) ? Just(func(value1)) : Nothing<T2>();
161 }
162
163#endregion
164
169 {
170 T1 value1;
171 T2 value2;
172
173 if (first.MatchJust(out value1) && second.MatchJust(out value2))
174 {
175 return Just(Tuple.Create(value1, value2));
176 }
177
178 return Nothing<Tuple<T1, T2>>();
179 }
180
181#if !CSX_REM_EITHER_FUNC
186 {
187 if (either.Tag == EitherType.Right) {
188 return Maybe.Just(((Right<TLeft, TRight>)either).Value);
189 }
190 return Maybe.Nothing<TRight>();
191 }
192#endif
193 }
194
198#if !CSX_MAYBE_INTERNAL
199 public
200#endif
201 internal static class MaybeExtensions
202 {
203#region Alternative Match Methods
204
208 public static void Match<T>(this Maybe<T> maybe, Action<T> ifJust, Action ifNothing)
209 {
210 T value;
211
212 if (maybe.MatchJust(out value))
213 {
214 ifJust(value);
215
216 return;
217 }
218
219 ifNothing();
220 }
221
225 public static void Match<T1, T2>(this Maybe<Tuple<T1, T2>> maybe, Action<T1, T2> ifJust, Action ifNothing)
226 {
227 T1 value1;
228 T2 value2;
229
230 if (maybe.MatchJust(out value1, out value2))
231 {
232 ifJust(value1, value2);
233
234 return;
235 }
236
237 ifNothing();
238 }
239
243 public static bool MatchJust<T1, T2>(this Maybe<Tuple<T1, T2>> maybe, out T1 value1, out T2 value2)
244 {
245 Tuple<T1, T2> value;
246
247 if (maybe.MatchJust(out value))
248 {
249 value1 = value.Item1;
250 value2 = value.Item2;
251
252 return true;
253 }
254
255 value1 = default;
256 value2 = default;
257
258 return false;
259 }
260
261#endregion
262
267 public static Maybe<T> ToMaybe<T>(this T value)
268 {
269 return Maybe.Return(value);
270 }
271
275 public static Maybe<T2> Bind<T1, T2>(this Maybe<T1> maybe, Func<T1, Maybe<T2>> func)
276 {
277 return Maybe.Bind(maybe, func);
278 }
279
283 public static Maybe<T2> Map<T1, T2>(this Maybe<T1> maybe, Func<T1, T2> func)
284 {
285 return Maybe.Map(maybe, func);
286 }
287
288#region Linq Operators
289
294 Func<TSource, TResult> selector)
295 {
296 return Maybe.Map(maybe, selector);
297 }
298
303 Func<TSource, Maybe<TValue>> valueSelector,
304 Func<TSource, TValue, TResult> resultSelector)
305 {
306 return maybe
307 .Bind(sourceValue =>
308 valueSelector(sourceValue)
309 .Map(resultValue => resultSelector(sourceValue, resultValue))
310 );
311 }
312
313#endregion
314
315#region Do Semantic
316
320 public static void Do<T>(this Maybe<T> maybe, Action<T> action)
321 {
322 T value;
323
324 if (maybe.MatchJust(out value))
325 {
326 action(value);
327 }
328 }
329
333 public static void Do<T1, T2>(this Maybe<Tuple<T1, T2>> maybe, Action<T1, T2> action)
334 {
335 T1 value1;
336 T2 value2;
337
338 if (maybe.MatchJust(out value1, out value2))
339 {
340 action(value1, value2);
341 }
342 }
343
344#endregion
345
349 public static bool IsJust<T>(this Maybe<T> maybe)
350 {
351 return maybe.Tag == MaybeType.Just;
352 }
353
357 public static bool IsNothing<T>(this Maybe<T> maybe)
358 {
359 return maybe.Tag == MaybeType.Nothing;
360 }
361
366 public static T FromJust<T>(this Maybe<T> maybe)
367 {
368 T value;
369
370 if (maybe.MatchJust(out value))
371 {
372 return value;
373 }
374
375 return default;
376 }
377
382 public static T FromJustOrFail<T>(this Maybe<T> maybe, Exception exceptionToThrow = null)
383 {
384 T value;
385
386 if (maybe.MatchJust(out value))
387 {
388 return value;
389 }
390
391 throw exceptionToThrow ?? new ArgumentException("Value empty.");
392 }
393
397 public static T GetValueOrDefault<T>(this Maybe<T> maybe, T noneValue)
398 {
399 T value;
400
401 return maybe.MatchJust(out value) ? value : noneValue;
402 }
403
407 public static T2 MapValueOrDefault<T1, T2>(this Maybe<T1> maybe, Func<T1, T2> func, T2 noneValue)
408 {
409 T1 value1;
410
411 return maybe.MatchJust(out value1) ? func(value1) : noneValue;
412 }
413
418 public static T2 MapValueOrDefault<T1, T2>(this Maybe<T1> maybe, Func<T1, T2> func, Func<T2> noneValueFactory)
419 {
420 T1 value1;
421
422 return maybe.MatchJust(out value1) ? func(value1) : noneValueFactory();
423 }
424
429 public static IEnumerable<T> ToEnumerable<T>(this Maybe<T> maybe)
430 {
431 T value;
432
433 if (maybe.MatchJust(out value))
434 {
435 return Enumerable.Empty<T>()
436 .Concat(new[] { value });
437 }
438
439 return Enumerable.Empty<T>();
440 }
441 }
442}
EitherType Tag
Definition Either.cs:36
Models a CSharpx.Maybe when contains a value.
Definition Maybe.cs:88
Just(T value)
Definition Maybe.cs:89
T Value
The wrapped value.
Definition Maybe.cs:98
Provides convenience extension methods for CSharpx.Maybe.
Definition Maybe.cs:202
static void Match< T1, T2 >(this Maybe< Tuple< T1, T2 > > maybe, Action< T1, T2 > ifJust, Action ifNothing)
Provides pattern matching using System.Action delegates over maybe with tupled wrapped value.
Definition Maybe.cs:225
static T FromJust< T >(this Maybe< T > maybe)
Extracts the element out of a CSharpx.Just<T> and returns a default value if its argument is CSharpx....
Definition Maybe.cs:366
static Maybe< TResult > Select< TSource, TResult >(this Maybe< TSource > maybe, Func< TSource, TResult > selector)
Map operation compatible with Linq.
Definition Maybe.cs:293
static void Do< T1, T2 >(this Maybe< Tuple< T1, T2 > > maybe, Action< T1, T2 > action)
If contans a value executes an System.Action<T1, T2> delegate over it.
Definition Maybe.cs:333
static Maybe< TResult > SelectMany< TSource, TValue, TResult >(this Maybe< TSource > maybe, Func< TSource, Maybe< TValue > > valueSelector, Func< TSource, TValue, TResult > resultSelector)
Bind operation compatible with Linq.
Definition Maybe.cs:302
static void Do< T >(this Maybe< T > maybe, Action< T > action)
If contains a value executes an System.Action<T> delegate over it.
Definition Maybe.cs:320
static void Match< T >(this Maybe< T > maybe, Action< T > ifJust, Action ifNothing)
Provides pattern matching using System.Action delegates.
Definition Maybe.cs:208
static Maybe< T2 > Map< T1, T2 >(this Maybe< T1 > maybe, Func< T1, T2 > func)
Transforms this maybe value by using a specified mapping function.
Definition Maybe.cs:283
static T GetValueOrDefault< T >(this Maybe< T > maybe, T noneValue)
If contains a values returns it, otherwise returns noneValue .
Definition Maybe.cs:397
static IEnumerable< T > ToEnumerable< T >(this Maybe< T > maybe)
Returns an empty list when given CSharpx.Nothing<T> or a singleton list when given a CSharpx....
Definition Maybe.cs:429
static Maybe< T2 > Bind< T1, T2 >(this Maybe< T1 > maybe, Func< T1, Maybe< T2 > > func)
Invokes a function on this maybe value that itself yields a maybe.
Definition Maybe.cs:275
static bool IsJust< T >(this Maybe< T > maybe)
Returns true iffits argument is of the form CSharpx.Just<T>.
Definition Maybe.cs:349
static bool IsNothing< T >(this Maybe< T > maybe)
Returns true iffits argument is of the form CSharpx.Nothing<T>.
Definition Maybe.cs:357
static Maybe< T > ToMaybe< T >(this T value)
Equivalent to monadic CSharpx.Maybe.Return<T> operation. Builds a CSharpx.Just<T> value in case value...
Definition Maybe.cs:267
static T2 MapValueOrDefault< T1, T2 >(this Maybe< T1 > maybe, Func< T1, T2 > func, T2 noneValue)
If contains a values executes a mapping function over it, otherwise returns noneValue .
Definition Maybe.cs:407
static bool MatchJust< T1, T2 >(this Maybe< Tuple< T1, T2 > > maybe, out T1 value1, out T2 value2)
Matches a value returning true and tupled value itself via two output parameters.
Definition Maybe.cs:243
static T FromJustOrFail< T >(this Maybe< T > maybe, Exception exceptionToThrow=null)
Extracts the element out of a CSharpx.Just<T> and throws an error if its argument is CSharpx....
Definition Maybe.cs:382
The Maybe type models an optional value. A value of type Maybe a either contains a value of type a (r...
Definition Maybe.cs:33
static Maybe< T2 > Bind< T1, T2 >(Maybe< T1 > maybe, Func< T1, Maybe< T2 > > func)
Sequentially compose two actions, passing any value produced by the first as an argument to the secon...
Definition Maybe.cs:142
MaybeType Tag
Type discriminator.
Definition Maybe.cs:42
static Maybe< T2 > Map< T1, T2 >(Maybe< T1 > maybe, Func< T1, T2 > func)
Transforms an maybe value by using a specified mapping function.
Definition Maybe.cs:156
static Maybe< TRight > FromEither< TLeft, TRight >(Either< TLeft, TRight > either)
Maps Either Right value to Maybe Just, otherwise Maybe Nothing.
Definition Maybe.cs:185
static Maybe< T > Return< T >(T value)
Inject a value into the monadic CSharpx.Maybe<T> type.
Definition Maybe.cs:134
static Just< T > Just< T >(T value)
Builds the case when CSharpx.Maybe contains a value.
Definition Maybe.cs:122
bool MatchNothing()
Matches an empty value returning true.
Definition Maybe.cs:59
Maybe(MaybeType tag)
Definition Maybe.cs:34
bool MatchJust(out T value)
Matches a value returning true and value itself via output parameter.
Definition Maybe.cs:49
static Maybe< Tuple< T1, T2 > > Merge< T1, T2 >(Maybe< T1 > first, Maybe< T2 > second)
If both maybes contain a value, it merges them into a maybe with a tupled value.
Definition Maybe.cs:168
static Maybe< T > Nothing< T >()
Builds the empty case of CSharpx.Maybe.
Definition Maybe.cs:114
Models a CSharpx.Maybe when in empty state.
Definition Maybe.cs:76
EitherType
Definition Either.cs:14
MaybeType
Discriminator for CSharpx.Maybe.
Definition Maybe.cs:19