Оператор ?? почему-то не работал с ValueOption[T]. Я решил исправить эту недоработку, но чтобы не вставать два раза обобщил это дело до поддержки HasValue/Value паттерна.
Теперь оператор ?? будет работать с любым типом у которого есть свойства или поля HasValue : bool и Value.
Например, теперь можно написать свой вариант целочисленного option использующего одно из значений в качестве индикатора отсутствия результата:
using Nemerle.Utility;
using System.Console;
[Record]
struct IntOption
{
public Value : int;
public HasValue : bool { get { Value >= 0 } }
}
module Program
{
Main() : void
{
WriteLine(IntOption(42) ?? -2);
WriteLine(IntOption(0) ?? -2);
WriteLine(IntOption(-1) ?? -200);
}
}
Этот кода выведет:
42
0
-200
Добавить поддержку паттерн-матчинга к такому типу можно так:
using Nemerle.Utility;
using System.Console;
[Record]
[ExtensionPattern(IntSome(value) = IntOption where(HasValue=true, Value=value))]
[ExtensionPattern(IntNone() = IntOption where(HasValue=false))]
struct IntOption
{
public Value : int;
public HasValue : bool { get { Value >= 0 } }
}
...
match (IntOption(-1))
{
| IntSome(x) => WriteLine($"IntSome($x)")
| IntNone => WriteLine("None")
}
За одно улучшил генерацию кода этим макросом. Теперь он вводит переменную, если первый параметр не простое имя и использует паттер-матчинг для option[T].