Skip to content

Commit a515572

Browse files
authored
Update sum_types.md
Sum type variables
1 parent 9a55d05 commit a515572

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

docs/sum_types.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,51 @@ unsigned count(tree&&);
264264
```
265265
266266
because 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

Comments
 (0)