2015-01-02 3 views
4

꽤 많은 생성자가있는 공용체 유형을 사용할 때 거의 항상 단일 함수에서 많은 로직을 구현합니다. 즉 하나의 함수에서 모든 사례를 처리합니다. 때로는 하나의 함수를 분리하는 논리를 추출하고 싶지만 하나의 "생성자"만 매개 변수로 허용하는 함수를 가질 수는 없습니다.긴 패턴 일치 기능을 피하는 방법은 무엇입니까?

예 : 우리는 전형적인 "표현"유형이 있다고 가정 : 다음

type Formula =  
| Operator of OperatorKind * Formula * Formula 
| Number of double 
| Function of string * Formula list 
[...] 

를, 우리는 표현을 계산하고 싶습니다 :

let rec calculate efValues formula = 
match formula with 
    | Number n -> [...] 
    | Operator (kind, lFormula, rFormula) -> [...] 
    | [...] 

이러한 기능은 모든 매우 길고 성장이 될 것입니다 새로운 수식 생성자. 그런 코드를 피하고 정리하는 방법은 무엇입니까? 긴 패턴 일치 구조가 필연적입니까?

+0

"하나의 대/소문자 구분 논리를위한 논리를 추출하지만, 단 하나의"생성자 "를 매개 변수로 허용하는 기능을 가질 수는 없습니다.". 의사 코드로 예제를 줄 수 있습니까? – Christian

+0

사실, 네가 할 수있다 :'let test (Some (x)) = x' 이것은 경고를 준다. 그러나 나는 그것이 당신이 원하는 것을 생각한다? – mydogisbox

+0

@mydogisbox : 패턴이 일치하지 않으면 런타임 예외가 발생합니다.나는 하나 이상의 경우가있는 것을 위해 그것을 사용하지 않을 것입니다.) – scrwtp

답변

3

당신은 명시 적으로 튜플 사용하여 Formula 노동 조합의 Operator 경우를 정의 할 수 있습니다 :이 작업을 수행 할 경우

type Formula =  
| Operator of (string * Formula * Formula) 
| Number of double 

는, 컴파일러가 모두 Operator(name, left, right)를 사용하여 하나의 인자 Operator args을 사용하면 패턴 일치를하게됩니다, 당신 때문에 과 같이 쓸 수있다 :이 조금 혼란 찾을 것

let evalOp (name, l, r) = 0.0 
let eval f = 
    match f with 
| Number n -> 0.0 
| Operator args -> evalOp args 

를, 그래서 유형 정의에 더 명시 적으로 더 나은 및 EQ 인 (명명 된 튜플을 사용할 수 있습니다 위의 uivalent) :

type OperatorInfo = string * Formula * Formula 
and Formula =  
| Operator of OperatorInfo 
| Number of double 

아니면 더 명시 적 및 기록 사용 : 다음

type OperatorInfo = 
{ Name : string 
    Left : Formula 
    Right : Formula } 
and Formula =  
| Operator of OperatorInfo 
| Number of double 

당신이 패턴 일치 다음 중 하나를 사용 할 수 있습니다

| Operator args -> (...) 
| Operator { Name = n; Left = l; Right = r } -> (...) 
+0

나는 주어진 케이스 생성자에 대한 인수의 수보다는 DU에서의 케이스의 수를 의미하는 질문을했다. 즉, 더 많은 사례가 추가되면서 '계산'기능이 너무 길어질 것입니다. – ildjarn

+0

@ildjarn 명시 적 튜플 또는 레코드를 사용하여 입력 내용이 사례의 내용 인 각 사례에 대해 함수를 정의 할 수 있다고 말한 것 같습니다. – mydogisbox

2

I을 일반적으로 단일 함수에서 모든 사례를 처리하려고한다고 가정합니다. 이것이 노조의 주요 판매 포인트입니다. 모든 경우를 한 가지 또는 다른 방식으로 처리해야합니다. 즉, 어디에서 왔는지 알 수 있습니다.

let doSomethingForOneCase (form: Formula) = 
    match form with 
    | Formula (op, l, r) -> 
     let result = (...) 
     Some result 
    | _ -> None 

을 그리고 방법은에서 적절한 무엇이든에 없음을 처리하지 : 나는 큰 노동 조합이 있고 단 하나의 사건에 대해 걱정

경우에, 나는 옵션에 결과를 포장, 이런 식으로 처리 할 것 전화 사이트.

이 기호는 partial active patterns에 필요한 서명과 일치하므로 다른 일치 식의 대소 문자로이 함수를 사용해야한다고 결정한 경우 활성 패턴으로 쉽게 마무리하여 멋진 기호를 얻을 수 있습니다 통사론.