【问题标题】:Using active patterns within discrimated union type declarations在有区别的联合类型声明中使用活动模式
【发布时间】:2012-12-12 14:31:26
【问题描述】:

是否可以在有区别的联合类型声明中使用活动模式?

更准确地说,考虑以下玩具示例:

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!"

【问题讨论】:

标签: f# discriminated-union active-pattern


【解决方案1】:

您的问题表明,阴性测试是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

【讨论】:

    【解决方案2】:

    这不是最好的解决方案,但您可以这样做:

    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
    

    【讨论】:

      【解决方案3】:

      好的,我想我找到了解决方案:首先声明类型,然后在其外部声明活动模式,最后使用 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.
      

      【讨论】:

      • 我认为这表明了一个设计问题:内在操作ToString 依赖于辅助功能(|Negative|_|)。这样做很尴尬是有充分理由的。
      猜你喜欢
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 2017-10-05
      • 1970-01-01
      相关资源
      最近更新 更多