2012-10-04 4 views
3

부분 활성 패턴 및 사용 가능한 여러 가지 패턴을 포함하여 F #에서 활성 패턴을 정의하고 사용하는 방법을 이해합니다. 예 :활성 패턴에 대해 혼동이 있음

let (|Big|Small|) animal = if animal.IsBig then Big(animal) else Small(animal) 
let f = function | Big(_) -> "big" |Small(_) -> "small 

는 그러나, 나는 let 바인딩, 인수 및 다른 장소에서 활동 패턴과 차별 노동 조합을 사용에 대한 혼란 스러워요. 예를 들어 MSDN에는 다음 코드가 있습니다.

let GetSubstring1 (Slice(p0, p1, text)) = 
    printfn "Data begins at %d and ends at %d in string %s" p0 p1 text 
    text.[p0..p1] 

약간 혼란 스럽습니다.

특정 문제.

type Union = A of int * int | B of int 

은 어떻게 든에만 Union.A을 받아들이는 기능, 예를 만들 수의 내가 차별 노동 조합 있다고 가정 해 봅시다

let f (A(a, b)) = a + b 

이 경우에는 일치하지 않는 패턴이 있다고합니다. 그것을 만족시키는 방법이 있습니까?

+4

문제는 단순한 활성 패턴보다 일반적입니다. ** 모든 ** 패턴 일치는 즉시 나타나는 것보다 더 많은 상황에서 발생할 수 있습니다. – ildjarn

답변

8

@ildjarn이 지적한대로 이것은 모든 패턴에 적용됩니다. 그들은 match 절 (그리고 유사한 function)의 경우에 나타날 수 있지만, let 바운드 함수와 심지어 let 값 바인딩의 매개 변수 선언에서도 나타날 수 있습니다.

중요한 차이점은 let 인 경우 항상 성공할 패턴 만 사용하려는 것입니다. match 또는 function에는 여러 개의 절이 필요하므로이 중 하나가 실패하면 일치가 계속되고 다음 시도가 시도됩니다. 예를 들어

, 패턴 int를 받아로서 돌려 완벽한 다음은 string :

여기
let (|AsString|) (n:int) = n.ToString() 

당신이 그것을 사용하는 방법을 몇 가지 방법은 다음과 같습니다

let (AsString s) = 42   // Defines a value 's' of type string 
match 3 with AsString s -> s // Returns a value "3" of type string 
let convert (AsString s) = s // Defines a function 'int -> string' 
let convert = function AsString s -> s // Same as the previous line 

편집가 : 두 번째 질문에 대답하려면 이인 을 사용하는 경우210 패턴 (즉,

let f (A(a, b)) = a + b  // This gives compile-time warning 
f (B 42)      // This will fail at runtime 

을 당신은 정의해야하는 경우 : 그건 당신이 다른 차별 노조 케이스를 호출하는 경우 다음) (당신은 컴파일러 경고를하고 코드가 런타임에 실패 할 수 있음) 차별 노동 조합의 단 하나의 사건을 받아 함수 중 하나만 작동하는 경우 별도의 유형을 정의해야합니다.

type AInfo = int * int 
type Union = A of AInfo | B of int 

그럼 당신은 단지 AInfo을하는 함수를 작성할 수 있습니다 (그러나 두 옵션이 유효한 입력을 표시 어디에 당신은 여전히 ​​장소에서 Union 작업 할 수 있습니다).

관련 문제