2010年5月22日土曜日

HaskellのMaybeクラスをC#で作ってみた。その2


HaskellのMaybeクラスをC#で作ってみた
のMaybeクラスではdefault(T)が気持ち悪かったので、
ガサゴソと、クラスを分離してみた。



public interface IMaybe<T>
{
bool HasValue { get; }

T Value { get; }
}

public class Maybe<T> : IMaybe<T>
{
private readonly IMaybe<T> _maybeValue;

public Maybe(IMaybe<T> maybeValue)
{
_maybeValue = maybeValue;
}
public bool HasValue { get { return _maybeValue.HasValue; } }

public T Value { get { return _maybeValue.Value; } }

public T GetValue(T defaultValue)
{
if (HasValue)
{
return Value;
}
return defaultValue;
}

public static bool operator ==(Maybe<T> left, Maybe<T> right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if (ReferenceEquals(left, null))
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(Maybe<T> left, Maybe<T> right)
{
return !(left == right);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
{
return true;
}

Maybe<T> maybe = obj as Maybe<T>;
if (ReferenceEquals(maybe, null))
{
return false;
}
if (HasValue != maybe.HasValue)
{
return false;
}
if (HasValue)
{
return Value.Equals(maybe.Value);
}
return true;
}
public override int GetHashCode()
{
if (HasValue)
{
return Value.GetHashCode() * 751;
}
return 0;
}
public static explicit operator T(Maybe<T> maybe)
{
return maybe.Value;
}
public static Maybe<T> Nothing = new Maybe<T>(new Nothing<T>());

public static Maybe<T> Just(T value)
{
return new Maybe<T>(new Something<T>(value));
}

}

internal class Nothing<T> : IMaybe<T>
{
public bool HasValue
{
get { return false; }
}

public T Value
{
get
{
throw new InvalidOperationException("No Value");
}
}
}
internal class Something<T> : IMaybe<T>
{
private readonly T _value;
public Something(T value)
{
if (ReferenceEquals(value, null))
{
throw new ArgumentNullException("value is null");
}
_value = value;

}
public bool HasValue
{
get { return true; }
}

public T Value
{
get
{
return _value;
}
}
}




NUnitのテストコード
も公開しています。
.

0 件のコメント:

ラベル