@@ -264,3 +264,51 @@ unsigned count(tree&&);
264264```
265265
266266because those types are imaginary, and not known to the compiler.
267+
268+ Even though imaginary, C++ handles sum types just fine with one small caveat.
269+ In C++ variables have a type, one type, not two, nor more.
270+ Therefore, to define a variable of a sum type, sum special treatment is needed.
271+
272+ The following code snippet is not valid C++, becauce variables can't be defined having a concept as type.
273+ ```c++
274+ maybe m; // not valid
275+ list l; // not valid
276+ tree t; // not valid
277+ ```
278+
279+ In the following code snippet, variable definitions are valid, but also determined.
280+ Once ` m ` is defined as ` _nothing ` ; it can never be a ` _cons ` ; and vice versa.
281+ Similar holds for ` l ` and ` t ` .
282+ ``` c++
283+ _nothing m;
284+ _nil l;
285+ _leaf t;
286+ ```
287+
288+ We have to resort to C++ unions.
289+ ``` c++
290+ template <typename A>
291+ struct maybe_var {
292+ enum { is_nothing, is_some } _ d;
293+ union { _ nothing _ n; _ some<A > _ s; };
294+ maybe_var() : _ d{is_nothing} {}
295+ maybe_var(A a) : _ d{is_some}, _ s{a} {}
296+ operator bool() { return _ d == is_some; }
297+ };
298+ maybe_var<int > m0;
299+ maybe_var<int > m1 = 7;
300+ ```
301+
302+ And functions that shall accept such a C++ union as argument, require some consideration.
303+ ```c++
304+ template<typename R, typename A>
305+ struct FunctionOnMaybe {
306+ R operator()(_nothing) { /* … */ }
307+ R operator()(_some<A> s) { /* … */ }
308+ };
309+ template<typename R, typename A>
310+ R someFunction(maybe_var<A> m) {
311+ FunctionOnMaybe<R,A> f;
312+ return m ? f(m._s) : f(m._n);
313+ }
314+ ```
0 commit comments