I'm not familiar with the language you are writing in (being primarily a C programmer), but I gather the a variable of type "List<T>" is allowed to refer to either an object of type "ListNil<T>" or an object of type "ListCons<T>". "ListNil<T>" fills exactly the same role a "NULL" so what you have created is exactly a NULLable pointer, only with a different name and more complex syntax.
A rose by any other name still has thorns, and a NULL de-reference by any other name still causes a run-time-exception or worse.
All values are "created out of thin air". They are abstractions which we create and use to try to model "real" things. Values that are useful we re-use. Values that are not, we forget. NULL turns out to be useful.
Your argument against NULL would seem to apply equally to the value '0'. It is an arbitrary magical value - that the Romans seemed to manage with out. It is a value of every (numerical) type, yet it doesn't support being the divisor in a division. We really should eradicate it - that would get rid of all divide-by-zero errors forever.
Of course, divide-by-zero errors are not caused by the availability of a 0 value, but by the misuse of that value. Similarly NULL pointer de-reference errors are not caused by the availability of a 'NULL' value, but by the misuse of that value.