是否可以在被描述的联合类型声明中使用活动模式?
更准确地说,请考虑以下玩具示例:
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!"
现在假设我要覆盖T中的ToString()。在T的类型声明中我不能引用T_ToString,因为T_ToString尚未在那时声明。我无法在ToString()之前移动活动模式和T_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!"
答案 0 :(得分:4)
您的问题表明,对负面进行测试是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
答案 1 :(得分:3)
这不是最好的解决方案,但你可以这样做:
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
答案 2 :(得分:2)
好的,我认为我找到了一个解决方案:首先声明类型,然后在其外部声明活动模式,最后使用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.