Я не использовал библиотеку Maybe, но что-то вроде этого, похоже, отвечает всем требованиям:
import std.stdio;
struct Maybe(T)
{
private {
bool isNothing = true;
T value;
}
void opAssign(T val)
{
isNothing = false;
value = val;
}
void opAssign(Maybe!T val)
{
isNothing = val.isNothing;
value = val.value;
}
T get() @property
{
if (!isNothing)
return value;
else
throw new Exception("This is nothing!");
}
bool hasValue() @property
{
return !isNothing;
}
}
Maybe!int doSomething(in int k)
{
Maybe!int ret;
if (k < 10)
ret = 3;
return ret;
}
void main()
{
auto retVal = doSomething(5);
assert(retVal.hasValue);
writeln(retVal.get);
retVal = doSomething(15);
assert(!retVal.hasValue);
writeln(retVal.hasValue);
}
При некоторой перегрузке творческого оператора структура Maybe может вести себя вполне естественно. Кроме того, я шаблонизировал структуру Maybe, поэтому ее можно использовать с любым типом.