2009-12-02 4 views
4

정적이 아닌 public 멤버 활성 패턴이 허용되는지는 잘 모르겠지만 컴파일러가 불평하지 않고 정의 할 수 있습니다. 허용되는 경우 일치하는 구문은 무엇입니까? 컴파일러에서 Foo에 대한 형식 불일치를 FooBar2.doSomething에 제공하고 있습니다. 'a -> Choice<'b,'c>F # 비 정적 멤버로 활성 패턴

// 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 ->() 

답변

6

활성 패턴을 구성원으로 사용해서는 안됩니다. 사실이 컴파일은 우리가 고칠 컴파일러 버그입니다 (보고서 덕분에 :)). 활성 패턴을 정의하려면 로컬 또는 모듈 바인딩 "let"을 사용하십시오.

+1

흠, 적어도 정적 버전을 가지고 있지 않으면 나를 네임 스페이스가 아닌 모듈을 사용해야하는 것으로 압박하고 있습니다. 이것에 대한 나의 유일한 관심은 둘 사이에 똑같은 이름/행동을 나누는 것입니다. 이로 인해 반복되는 이름이 생길 수 있습니다. 차라리 모든 네트워크 코드를 네임 스페이스 네트워크에 보관하고 CLR이 모든 정적 클래스로 변환한다고 생각하는 모듈 네트워크도 보유하지 않을 것입니다. 그래서 나는 MyApp.Network.ModuleName.Identifier와 같은 것으로 끝날 것입니다. – gradbot

3

'a -> 'd -> Choice<unit,unit> 주어진 기대 나는이 작동하지 않습니다하지 놀랐어요, 나는 예를 활성 패턴 자연 의미 론적 해석을 볼 수 없습니다. Foo 패턴을 볼 때 사용할 인스턴스를 어떻게 알 수 있습니까? FooBar 사례의 인스턴스가 다를 수 있습니다 (불완전한 패턴 일치)? 여기에 문제에 대한 우아한 해결책이없는 것 같습니다. 솔직히 정적 인 경우조차도 놀랍습니다. 그리고 어떤 종류의 멤버로도 활성 패턴의 정의를 다루는 스펙에는 아무것도 표시되지 않습니다.

0

멤버 인식기는 버전 1.9.9.9부터 사용되지 않은 것으로 보입니다. 정적 멤버 일지라도 나는 그것이 인식기 과부하를 허용했기 때문에 수치 스럽다고 생각한다. Type, MemberInfo 등등의 'Name'인식자를 가질 수 있습니다. 이제 'Type_Name'이 필요합니다. 'Member_Name'등으로 이름 충돌을 피할 수 있습니다. 단지 '이름'이 더 좋았습니다.