2014-11-14 1 views
3

내가 같은 옵션이 활성 패턴을 만들 수 없습니다 발견했습니다,하지만 난 경고없이 유사한 것들 두를 수 있습니다 :F #을 덮어 활성 패턴을 피

이 방법으로 일치
let (|A|B|C|) c = 
    if (c = 'a') then A 
    else if (c = 'b') then B 
    else C 

let (|A|B|D|) c = 
    if (c = '1') then A 
    else if (c = '2') then B 
    else D 

그래서 때

let check myvar = 
    match myvar with 
    | A -> printf "match A\n" 
    | n -> printf "match other %A\n" n 

이 발생합니다

check 'x' // match other 'x' 
check 'a' // match other 'a'  !! 
check '1' // match A 

내가 덮어 기존 활성 PA 약간의 걱정 예를 들어 (|Direct|Indirect|) (경로) 및 (|Alternating|Direct|) (현재)과 같은 서로 다른 의미 문맥 때문에 동일한 단어가 다른 패턴으로 나타날 수있는 상황에서 부주의하게 ttern 옵션을 사용할 수 없습니다.

이 상황을 어떻게 피할 수 있습니까?

답변

7

액티브 패턴의 음영 처리가 까다로울 수 있다는 것에 동의합니다. F #에서 구별 된 통합 사례와 레코드 레이블을 얻는 것과 같은 문제이지만 동의합니다. 유형의 경우 모호성을 해결하기 위해 항상 유형 이름을 포함 할 수 있습니다. 활성 패턴의 경우

, 당신은 모듈을 넣을 수 있습니다 - 예를 Pat1Pat2을 위해 :

module Pat1 = 
let (|A|B|C|) c = 
    if (c = 'a') then A 
    else if (c = 'b') then B 
    else C 

module Pat2 = 
let (|A|B|D|) c = 
    if (c = '1') then A 
    else if (c = '2') then B 
    else D 

그래서, 당신의 코드에서, 당신은 다음 Pat1.A 또는 Pat2.A처럼 완전한 이름을 사용할 수 있습니다

let check myvar = 
    match myvar with 
    | Pat1.A -> printf "match A\n" 
    | n -> printf "match other %A\n" n 
+0

이것은 매우 좋은 방법입니다. 감사! – vtortola

3

귀하의 우려는 단지 활성 패턴뿐만 아니라 일반적으로 섀도 ​​잉에 적용됩니다. 매개 변수와 반환 값이 동일하고 중복되는 대문자 이름을 갖는 두 개의 활성 패턴을 얼마나 자주 정의합니까? 일반적으로 유형은 잠재적 인 섀도 잉 문제를 완화합니다. 이 행을 따라 유형 주석은 친구입니다.