Tanoda
Maybe.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System;
10
11namespace Leap.Unity {
12 using Query;
13
14 public static class Maybe {
15 public static readonly NoneType None = new NoneType();
16
17 public static Maybe<T> Some<T>(T value) {
18 return new Maybe<T>(value);
19 }
20
21 public static void MatchAll<A, B>(Maybe<A> maybeA, Maybe<B> maybeB, Action<A, B> action) {
22 maybeA.Match(a => {
23 maybeB.Match(b => {
24 action(a, b);
25 });
26 });
27 }
28
29 public static void MatchAll<A, B, C>(Maybe<A> maybeA, Maybe<B> maybeB, Maybe<C> maybeC, Action<A, B, C> action) {
30 maybeA.Match(a => {
31 maybeB.Match(b => {
32 maybeC.Match(c => {
33 action(a, b, c);
34 });
35 });
36 });
37 }
38
39 public static void MatchAll<A, B, C, D>(Maybe<A> maybeA, Maybe<B> maybeB, Maybe<C> maybeC, Maybe<D> maybeD, Action<A, B, C, D> action) {
40 maybeA.Match(a => {
41 maybeB.Match(b => {
42 maybeC.Match(c => {
43 maybeD.Match(d => {
44 action(a, b, c, d);
45 });
46 });
47 });
48 });
49 }
50
51 public struct NoneType { }
52 }
53
59 public struct Maybe<T> : IEquatable<Maybe<T>>, IComparable, IComparable<Maybe<T>> {
60
64 public readonly static Maybe<T> None = new Maybe<T>();
65
69 public readonly bool hasValue;
70
74 public T valueOrDefault {
75 get {
76 T value;
77 if (TryGetValue(out value)) {
78 return value;
79 }
80 return default(T);
81 }
82 }
83
84 private readonly T _t;
85
91 public Maybe(T t) {
92 if (Type<T>.isValueType) {
93 hasValue = true;
94 } else {
95 hasValue = t != null;
96 }
97 _t = t;
98 }
99
104 public static Maybe<T> Some(T t) {
105 if (!Type<T>.isValueType && t == null) {
106 throw new ArgumentNullException("Cannot use Some with a null argument.");
107 }
108
109 return new Maybe<T>(t);
110 }
111
116 public bool TryGetValue(out T t) {
117 t = _t;
118 return hasValue;
119 }
120
124 public void Match(Action<T> ifValue) {
125 if (hasValue) {
126 ifValue(_t);
127 }
128 }
129
134 public void Match(Action<T> ifValue, Action ifNot) {
135 if (hasValue) {
136 if (ifValue != null) ifValue(_t);
137 } else {
138 ifNot();
139 }
140 }
141
146 public K Match<K>(Func<T, K> ifValue, Func<K> ifNot) {
147 if (hasValue) {
148 if (ifValue != null) {
149 return ifValue(_t);
150 } else {
151 return default(K);
152 }
153 } else {
154 return ifNot();
155 }
156 }
157
162 public T ValueOr(T customDefault) {
163 if (hasValue) {
164 return _t;
165 } else {
166 return customDefault;
167 }
168 }
169
177 public Maybe<T> ValueOr(Maybe<T> maybeCustomDefault) {
178 if (hasValue) {
179 return this;
180 } else {
181 return maybeCustomDefault;
182 }
183 }
184
185 public Query<T> Query() {
186 if (hasValue) {
187 return Values.Single(_t);
188 } else {
189 return Values.Empty<T>();
190 }
191 }
192
193 public override int GetHashCode() {
194 return hasValue ? _t.GetHashCode() : 0;
195 }
196
197 public override bool Equals(object obj) {
198 if (obj is Maybe<T>) {
199 return Equals((Maybe<T>)obj);
200 } else {
201 return false;
202 }
203 }
204
205 public bool Equals(Maybe<T> other) {
206 if (hasValue != other.hasValue) {
207 return false;
208 } else if (hasValue) {
209 return _t.Equals(other._t);
210 } else {
211 return true;
212 }
213 }
214
215 public int CompareTo(object obj) {
216 if (!(obj is Maybe<T>)) {
217 throw new ArgumentException();
218 } else {
219 return CompareTo((Maybe<T>)obj);
220 }
221 }
222
223 public int CompareTo(Maybe<T> other) {
224 if (hasValue != other.hasValue) {
225 return hasValue ? 1 : -1;
226 } else if (hasValue) {
227 IComparable<T> ct = _t as IComparable<T>;
228 if (ct != null) {
229 return ct.CompareTo(other._t);
230 } else {
231 IComparable c = _t as IComparable;
232 if (c != null) {
233 return c.CompareTo(other._t);
234 } else {
235 return 0;
236 }
237 }
238 } else {
239 return 0;
240 }
241 }
242
243 public static bool operator ==(Maybe<T> maybe0, Maybe<T> maybe1) {
244 return maybe0.Equals(maybe1);
245 }
246
247 public static bool operator !=(Maybe<T> maybe0, Maybe<T> maybe1) {
248 return !maybe0.Equals(maybe1);
249 }
250
251 public static bool operator >(Maybe<T> maybe0, Maybe<T> maybe1) {
252 return maybe0.CompareTo(maybe1) > 0;
253 }
254
255 public static bool operator >=(Maybe<T> maybe0, Maybe<T> maybe1) {
256 return maybe0.CompareTo(maybe1) >= 0;
257 }
258
259 public static bool operator <(Maybe<T> maybe0, Maybe<T> maybe1) {
260 return maybe0.CompareTo(maybe1) < 0;
261 }
262
263 public static bool operator <=(Maybe<T> maybe0, Maybe<T> maybe1) {
264 return maybe0.CompareTo(maybe1) <= 0;
265 }
266
267 public static implicit operator Maybe<T>(T t) {
268 return new Maybe<T>(t);
269 }
270
271 public static implicit operator Maybe<T>(Maybe.NoneType none) {
272 return None;
273 }
274 }
275}
A struct that represents a value that could or could not exist. Unlike the built-int nullable types,...
Definition: Maybe.cs:59
bool Equals(Maybe< T > other)
Definition: Maybe.cs:205
static void MatchAll< A, B, C >(Maybe< A > maybeA, Maybe< B > maybeB, Maybe< C > maybeC, Action< A, B, C > action)
Definition: Maybe.cs:29
T ValueOr(T customDefault)
If this Maybe has a value, returns the value, otherwise returns the argument custom default value.
Definition: Maybe.cs:162
static readonly NoneType None
Definition: Maybe.cs:15
Maybe< T > ValueOr(Maybe< T > maybeCustomDefault)
Returns this Maybe if it has a value, otherwise returns the argument Maybe value. Useful for overlayi...
Definition: Maybe.cs:177
static void MatchAll< A, B, C, D >(Maybe< A > maybeA, Maybe< B > maybeB, Maybe< C > maybeC, Maybe< D > maybeD, Action< A, B, C, D > action)
Definition: Maybe.cs:39
void Match(Action< T > ifValue, Action ifNot)
If this Maybe has a value, the first delegate is called with that value, else the second delegate is ...
Definition: Maybe.cs:134
static void MatchAll< A, B >(Maybe< A > maybeA, Maybe< B > maybeB, Action< A, B > action)
Definition: Maybe.cs:21
void Match(Action< T > ifValue)
If this Maybe has a value, the delegate is called with that value.
Definition: Maybe.cs:124
readonly bool hasValue
Returns whether or not this Maybe contains a value.
Definition: Maybe.cs:69
static Maybe< T > Some(T t)
Constructs a Maybe given a specific value. This value needs to always be non-null if the type is a re...
Definition: Maybe.cs:104
static Maybe< T > Some< T >(T value)
Definition: Maybe.cs:17
override int GetHashCode()
Definition: Maybe.cs:193
static bool operator<=(Maybe< T > maybe0, Maybe< T > maybe1)
Definition: Maybe.cs:263
T valueOrDefault
Gets the value, or the type's default if it doesn't exist.
Definition: Maybe.cs:74
static bool operator>=(Maybe< T > maybe0, Maybe< T > maybe1)
Definition: Maybe.cs:255
Maybe(T t)
Constructs a Maybe given a value. If the value is not null, this maybe will have a value....
Definition: Maybe.cs:91
int CompareTo(object obj)
Definition: Maybe.cs:215
static bool operator==(Maybe< T > maybe0, Maybe< T > maybe1)
Definition: Maybe.cs:243
static bool operator<(Maybe< T > maybe0, Maybe< T > maybe1)
Definition: Maybe.cs:259
int CompareTo(Maybe< T > other)
Definition: Maybe.cs:223
override bool Equals(object obj)
Definition: Maybe.cs:197
Query< T > Query()
Definition: Maybe.cs:185
static bool operator!=(Maybe< T > maybe0, Maybe< T > maybe1)
Definition: Maybe.cs:247
static bool operator>(Maybe< T > maybe0, Maybe< T > maybe1)
Definition: Maybe.cs:251
bool TryGetValue(out T t)
If this Maybe has a value, the out argument is filled with that value and this method returns true,...
Definition: Maybe.cs:116
K Match< K >(Func< T, K > ifValue, Func< K > ifNot)
If this Maybe has a value, the first delegate is called with that value, else the second delegate is ...
Definition: Maybe.cs:146
A Query object is a type of immutable ordered collection of elements that can be used to perform usef...
Definition: Query.cs:90