Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using active patterns within discrimated union type declarations

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!"
like image 283
Mo B. Avatar asked Dec 12 '12 14:12

Mo B.


1 Answers

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
like image 74
Daniel Avatar answered Sep 23 '22 08:09

Daniel