Type unions in D

Jeremie Pelletier jeremiep at gmail.com
Tue Sep 15 19:22:49 PDT 2009


Justin Johansson Wrote:

> bearophile Wrote:
> 
> > Justin Johansson:
> > > What's the best way of emulating a system of quantified type unions in D  (D1)?
> > 
> > Having nullable values may be useful, having nonnull class references can probably be very useful, having tagged unions (I am talking as C unions here) can be useful. But can you show me some usercases/purposes for what you are asking for? I think other people too here are curious.
> 
> Thanks for asking.  Here's a use case.  Suppose you have a container class which represents a list of numbers.  Let's call this class ListOfNums. Now a ListOfNums can contain zero or more numbers.  Now you want a function called max that takes a ListOfNums, xs, as an argument and returns the number in the list, xs, that is greater than or equal to all other numbers in xs.
> 
> So if xs contains (3, 9, 9, 2), max( xs) returns 9.
> 
> Now it makes sense that xs should contain at least one number, so if xs contains just (3), max( xs) returns 3.
> 
> But what if xs contains no numbers i.e. xs = (), the empty list?  What should max( xs) return in the way of a meaningful result short of throwing an exception?
> 
> Put another way, what is the maximum number in an empty list of numbers?
> 
> If you allow the numbers in the list to be real, then I suppose you could return NaN but there is no way of expressing NaN if the numbers you are dealing with are purely integer .. and it certainly is not a good idea to make a function that is dealing purely with integers to return a real just allow the corner case to return NaN (a real).
> 
> An elegant solution to this problem is to specify the max function as taking a quantified list of zero or more numbers and returning another quantified list of numbers which may contain either zero numbers or just one number: zero numbers if the argument list is empty and a single number (being the maximum number in the argument list) if the argument number list is non-empty. 
> 
> The important point in this solution is realizing a type system that treats a list of zero_or_one numbers, a list of zero numbers, a list of zero_or_more numbers, etc, as distinct types.
> 
> Trust this makes sense.
> 
> <JJ/>
> 

You don't need a variant type for such a thing. A simple template will do the job. As for the max of an empty set, you can just return zero.

class ListOfNums(T) if(isNumeric!T) {
    T max() const {
        T max = 0;
        foreach(n; _nums) if(n > max) max = n;
        return max;
    }
    T[] _nums;
}

It's been too long since I last used D1 so the above may use D2 only features.




More information about the Digitalmars-d mailing list