# [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
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

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:

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

```