[Mono-dev] Lang Theory Question
Jonathan Pryor
jonpryor at vt.edu
Fri Feb 1 22:10:06 EST 2008
On Fri, 2008-02-01 at 20:56 -0500, Scott Peterson wrote:
> I'm a sucker for syntactic sugar. There is one little trick which I've
> been trying and failing to do - it turns about to be impossible
It's not as impossible as you think, depending on the tradeoffs you're
willing to make.
> One nice thing about nullable types is the non-standard behavior of
> the assignment (=) operator. For example:
>
> int? val = 5;
> val = 6;
>
> is shorthand for:
>
> Nullable<int> val = new Nullable<int> (5);
> val.Value = 6;
>
> I am working with a struc similar to Nullable and I'd like to be able
> to use the assignment operator in a similar way.
And you can, you just can't think of it in terms of overloading
assignment. Instead, think of in terms of overloading the object
coercion operators...because that's what you can do:
struct MyNullable<T> where T : struct {
public bool HasValue { get; private set; }
public T Value { get; private set; }
public MyNullable (T t)
{
Value = t;
HasValue = true;
}
public static implicit operator MyNullable<T> (T value)
{
return new MyNullable<T> (value);
}
public static implicit operator MyNullable<T> (T? value)
{
if (value == null)
return new MyNullable<T> ();
return new MyNullable<T> ((T) value);
}
}
This _almost_ allows your desired usage:
MyNullable<int> a = 5; // works
MyNullalbe<int> b = null; // error
MyNullable<int> c = (int?) null; // works
Of course, this always works too:
MyNullable<int> d = new MyNullable<int> ();
Or we could do `MyNullable<int> e = MyNullable<int>.Null;` if we modify
MyNullable<T> to add:
public static readonly MyNullable<T> Null = new MyNullable<T>
();
I'm partial to the `(int?) null` version, as it's shorter.
And then, for complete insanity...use a Monad; from:
http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx
Relevant excerpt:
class Maybe<T>
{
public readonly static Maybe<T> Nothing = new Maybe<T>();
public T Value { get; private set; }
public bool HasValue { get; private set; }
Maybe()
{
HasValue = false;
}
public Maybe(T value)
{
Value = value;
HasValue = true;
}
}
public static Maybe<T> ToMaybe<T>(this T value)
{
return new Maybe<T>(value);
}
public static Maybe<U> SelectMany<T, U>(this Maybe<T> m, Func<T, Maybe<U>> k)
{
if (!m.HasValue)
return Maybe<U>.Nothing;
return k(m.Value);
}
var r = from x in 5.ToMaybe()
from y in Maybe<int>.Nothing
select x + y;
Console.WriteLine(r.HasValue ? r.Value.ToString() : "Nothing");
Quoth the article:
The result is "Nothing". We have implemented the null
propagation of nullables without explicit language support.
Tell me that isn't cool. :-)
- Jon
More information about the Mono-devel-list
mailing list