Использование активных шаблонов в объявлениях различаемого типа объединения
Можно ли использовать активные шаблоны в объявлениях различного типа объединения?
Чтобы быть более точным, рассмотрим следующий игрушечный пример:
type T =
| A of int
| B
let (|Negative|_|) t =
match t with
| A n when n < 0 -> Some ()
| _ -> None
let T_ToString = function
| Negative () -> "negative!"
| _ -> "foo!"
Теперь предположим, что я хочу переопределить ToString() в T. Внутри объявления типа T я не могу ссылаться на T_ToString, так как T_ToString еще не объявлен в этой точке. Я не могу переместить активный шаблон и T_ToString до ToString(), потому что T еще не объявлен в этой точке. Но это тоже не работает:
type T =
| A of int
| B
static member (|Negative|_|) t =
match t with
| A n when n < 0 -> Some ()
| _ -> None
override this.ToString () =
match this with
| Negative () -> "negative!"
| _ -> "foo!"
3 ответа
Ваш вопрос предполагает, что тестирование на негатив является внутренней операцией T
так что это должно быть частью его определения. Определение свойства является одним из способов сделать это:
type T =
| A of int
| B
member this.IsNegative =
match this with
| A n -> n < 0
| _ -> false
override this.ToString() =
if this.IsNegative then "negative!"
else "foo!"
Я не уверен, что активный шаблон все еще нужен, но если это так, то он тривиален:
let (|Negative|_|) (x: T) = if x.IsNegative then Some() else None
Это не самое лучшее решение, но вы можете сделать это:
type T =
| A of int
| B
static member internal ActivePattern t =
match t with
| A n when n < 0 -> Some ()
| _ -> None
override this.ToString () =
let (|Negative|_|) = T.ActivePattern
match this with
| Negative () -> "negative!"
| _ -> "foo!"
let (|Negative|_|) = T.ActivePattern
Хорошо, я думаю, что нашел решение: сначала объявить тип, затем объявить активный шаблон вне его, и, наконец, дополнить тип реализацией переопределения ToString().
type T =
| A of int
| B
let (|Negative|_|) t =
match t with
| A n when n < 0 -> Some ()
| _ -> None
type T with
override this.ToString() =
match this with
| Negative () -> "negative!"
| _ -> "foo!"
Тем не менее, это не очень приятно, так как я получаю предупреждение
warning FS0060: Override implementations in augmentations are now deprecated. Override implementations should be given as part of the initial declaration of a type.