views:

162

answers:

3

I'm not sure if non-static public member active patterns are allowed but you can define them without the compiler complaining. If they are allowed what's the syntax for matching against one? The compiler is giving me a type mismatch for Foo in FooBar2.doSomething. Expecting a 'a -> Choice<'b,'c> given 'a -> 'd -> Choice<unit,unit>

// No error in this class, static works great
type FooBar() = 
    static member (|Foo|Bar|) (x, y) =
        match x = y with
        | true -> Foo
        | false -> Bar

    member x.doSomething y =
        match x, y with
        | Foo -> ()
        | Bar -> ()

type FooBar2() = 
    member x.(|Foo|Bar|) y =
        match x = y with
        | true -> Foo
        | false -> Bar

    // compiler error on "Foo"    
    member x.doSomething y =
        match y with
        | Foo -> ()
        | Bar -> ()
+3  A: 

I'm not surprised that this doesn't work, and I can't see a natural semantic interpretation for instance active patterns. How do you know which instance to use when you see the Foo pattern? Could you have different instances for the Foo and Bar cases (and therefore an incomplete pattern match)? There doesn't seem to be an elegant resolution to the issues here. To be honest, I'm suprised that even the static case works, and I don't see anything in the spec addressing the definition of active patterns as members of any kind.

kvb
+3  A: 

Active patterns should not be used as members. The fact that these compile at all is a compiler bug that we'll fix (thanks for the report :) ). Use local or module-bound "let"s to define an active pattern.

Brian
Hmm, not having at least a static version pushes me into having to use a module and not just namespaces. My only concern about this is having the same name/behavoir split across the two. This may lead to repetitive naming. I'd rather keep all my network code in namespace Network and not also have a module Network which I believe the CLR turns into an all static class. So I would end up with something like MyApp.Network.ModuleName.Identifier
gradbot
A: 

Member recognizers seem to be out since version 1.9.9.9. even for static members. I think it is a shame because it allowed for recognizer overloading. I could have a 'Name' recognizer for Type, MemberInfo etc. Now I need to have a 'Type_Name'. 'Member_Name' etc. to avoid naming conflicts. Just 'Name' was nicer.

Thomas

Thomas