Is it possible to use active patterns within discrimated union type declarations?
To be more precise, consider the following toy example:
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!"
Now suppose I want to override ToString() in T. Inside T's type declaration I can't refer to T_ToString since T_ToString is not yet declared at that point. I can't move the active pattern and T_ToString before ToString() because T is not yet declared at that point. But this doesn't work either:
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!"
                Your question suggests that testing for negative is an intrinsic operation of T, so it should be part of its definition. Defining a property is one way to do that:
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!"
I'm not sure the active pattern is still needed, but if it is it's trivial:
let (|Negative|_|) (x: T) = if x.IsNegative then Some() else None
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With