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.