2011-04-11 6 views
5

가정하자 나는 다음과 같은 코드가 있습니다불완전한 패턴 일치를 필터로 사용 하시겠습니까?

type Vehicle = 
| Car of string * int 
| Bike of string 

let xs = [ Car("family", 8); Bike("racing"); Car("sports", 2); Bike("chopper") ] 

내가 좋아하는 루프에 대한 필수 불완전 패턴 매칭을 사용하여 목록 위의 필터링 할 수 있습니다

> for Car(kind, _) in xs do 
> printfn "found %s" kind;; 

found family 
found sports 
val it : unit =() 

하지만이 발생합니다 : warning FS0025: Incomplete pattern matches on this expression. For example, the value 'Bike (_)' may indicate a case not covered by the pattern(s). Unmatched elements will be ignored.

을 비교할 수없는 요소를 무시하는 것이 나의 의도이므로이 경고를 없앨 수 있습니까?

MatchFailureException을 발생시키지 않으면 서리스트 내포물로이 작업을 수행 할 수있는 방법이 있습니까? 예 : 그런 일 :

> [for Car(_, seats) in xs -> seats] |> List.sum;; 
val it : int = 10 
+0

나는 그 줄이 다음과 같을 것이라고 생각한다 : [버스 (_, 좌석) xs -> 좌석] |> List.sum ;; 권리? ;) –

+0

오, 알 겠어 !!! 2 대! 5 × 2 = 10! 주님, 도와주세요. –

+0

가족 용 자동차와 스포츠카이므로 8 + 2 = 10입니다. – Laurent

답변

10

2 년 전만해도 코드가 유효하며이를 수행하는 표준 방법이었습니다. 그런 다음 언어가 정리되었고 설계 결정은 명시적인 구문을 선호하는 것이 었습니다. 이런 이유로 경고를 무시하는 것이 좋지 않다고 생각합니다.

코드의 표준 교체는 다음과 같습니다

for x in xs do 
    match x with 
    | Car(kind, _) -> printfn "found %s" kind 
    | _ ->() 

, List.sumBy이 잘 맞는 것, 다른 하나 들어

(당신은 또한 상위 기능 패드 샘플에서이를 사용할 수 있습니다) :

0 :
xs |> List.sumBy (function Car(_, seats) -> seats | _ -> 0) 

당신이 함축 스틱을 선호하는 경우,이 명시 적 구문입니다

+0

흥미 롭습니다. 언급 한 "정리"를 설명하는 참조/링크가 있고이 변경에 대한 정당성에 대해 토론합니까? – gasche

+4

@gasche : 컴퓨터에 오래된 컴파일러가 있는데 버전 1.9.3.14와 1.9.6.16 사이에 변경 사항이 있음을 알려드립니다. 나는 이것에 대한 적절한 참조를 찾을 수 없지만, 그 릴리스 노트는 구문 단순화를 언급 : [링크] (http : //blogs.msdn.com/b/dsyme/archive/2008/08/29/detailed-release-notes-for-the-f-september-2008-ctp-release.aspx). 여기에도 토론이 있습니다 : [link] (http://cs.hubfs.net/forums/thread/12072.aspx). – Laurent

+1

패턴이 복잡하거나 (활성 패턴으로 정의 될 수 있기 때문에) 루프가 필터링 중인지 여부는 독자에게 항상 명확하지 않았습니다. 나는 이것이 (개인적으로, 나는이 문법을 즐겼다) 정당화일지도 모른다고 생각한다. 또한, 계산식에서 루프를 사용하는 방법을 알게되면 MatchFailureException이 발생합니다. – Laurent

5

당신은을 통해 경고를 침묵 할 수 #nowarn 지시 또는 --nowarn: 컴파일러 옵션 (FS0025 여기에 25 같은 경고 번호를 전달).

하지만 일반적으로 아니요, 다른 답변과 마찬가지로 명시 적으로 필터링하는 것이 가장 좋습니다 (예 : choose).

+1

나는이 경고를 로컬에서 사용 중지 할 가능성이 있습니다. 속성을 사용하여. 그러나 그럼에도 불구하고 고마워! :) –

5

일치하지 않는 사례를 무시하고 명시 적으로 명시하려면 List.choose을 사용하고 일치하지 않는 요소는 None을 반환하십시오. 코드는 다음과 같이 더 이상한 방식으로 작성 될 수 있습니다.

let _ = xs |> List.choose (function | Car(kind, _) -> Some kind 
            | _ -> None) 
      |> List.iter (printfn "found %s") 

let sum = xs |> List.choose (function | Car(_, seats)-> Some seats 
             | _ -> None) 
      |> List.sum 
+5

당신은'xs |> List.choose (Car (kind, _) -> Some (kind) | _ -> None) 함수와 같이 더 간결하게 만들 수 있습니다. ' –

+0

감사합니다. 당신의 대답은 또한 매우 도움이되었습니다 (그리고 당신과 Laurent 사이에서 결정하기가 어렵습니다). –

관련 문제