Well, if e.g. you use a discriminated union type

type Arg = Arg of string * int * int // line and col info

then e.g. a list of Args could be matched with e.g.

| Arg("on",_,_)::[] -> ...

Even if you use some other type (like a class), you could define an active pattern to match out the string inside that data type.

By on 8/16/2009 3:37 PM ()

I would like to go the active pattern route. What I am missing is how the comparison works - I have an override of Equal on the class which compares my class (LexToken) to a string (and to itslef) by comparing strings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    [<StructuralComparison(false)>]
    [<StructuralEquality(false)>]
    type LexToken =
        | LexToken of LexTokenObject
        | String of string
        
        member x.string = 
            match x with
                | LexToken tObject -> tObject.Text
                | String s -> s

        override x.Equals (y:obj) =
            match y with
            | :? LexToken as t -> t.string.Equals(x.string)
            | :? string as s -> s.Equals(x.string)
        
        interface IComparable with
            member x.CompareTo(y:obj) =
            match y with
            | :? LexToken as t -> t.string.CompareTo(x.string)
            | :? string as s -> s.CompareTo(x.string)

Now how an Active pattern over this class would look like? Or is this class an overkill and it would be better to use just a tuple?

By on 8/17/2009 5:18 AM ()

I would avoid the Equals() overload, I expect you do not want it.

Here's a sketch of how to do an active pattern over an arbitrary type:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 

type LexTokenObject = Blah of string * int  // something

type LexToken =
        | LexToken of LexTokenObject
        | String of string

let (|Str|_|) strValue lexToken =
    match lexToken with
    | String(s) -> if strValue = s then Some() else None
    | LexToken(Blah(s,_)) -> if strValue = s then Some() else None

let lts = [String "yes"; String "no"; LexToken(Blah("yes",42)); LexToken(Blah("no",99))]
for lt in lts do
    match lt with
    | Str "yes" -> printfn "yes"
    | _ -> printfn "no"

By on 8/17/2009 9:40 AM ()

this just did it:

1
let (|LexToken|) (t:LexToken) = LexToken(t.string)

Should've figured it out earlier

By on 8/17/2009 9:34 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper