2013-06-25 1 views
1

방금 ​​F #으로 게임을 시작했으며 다음 장난감 문제가 발생했습니다. 나는 이것을하기 위해 여러 가지 구문을 실험했지만 올바른 결과를 얻을 수는 없다.데이터 유형의 두 값을 비교하는 차별 유니트에 구성원 추가

I는 다음과 같은 유형

type Bar = 
    | DT of DateTime 
    | O of float 
    | H of float 
    | L of float 
    | C of float 

다음과 같은 두 가지 실시 예를 가질

let barPass = 
    [ 
     O(13200.0); 
     H(13220.0); 
     L(13190.0); 
     C(.0); 
    ] 

let barFail = 
    [ 
     O(13200.0); 
     H(13220.0); 
     L(13290.0); // low is greater than high which is invalid 
     C(.0); 
    ] 

I가 하이가 이상인지를 확인하기 위해 검사하는 새로운 부재를 추가 할 낮은. 다양한 패턴 매치를 시도했지만이 권리를 얻을 수없는 경우. 아래 코드는 올바르지 않지만 내가하려고하는 것을 보여주기에 충분할 것입니다.

type Bar with 
    member x.HiLoCheck() = 
     match x with 
     | x when (H >= L) -> true // <- compiler will not allow this 
     | _ -> false 

나는 이것을 튜플로 분해 할 필요가 있다고 생각하지만 여전히 너무 제한적인 f # 경험을 초월합니다.

답변

3

실제로 차별화 된 노동 조합 목록보다는 데이터 유형으로 레코드를 사용하고 싶다고 생각합니다. 그렇지 않으면 첫 번째 단계는 목록에 H과 'L'요소를 찾아야합니다.

뭔가 편집

type Bar = 
    { DateTime : DateTime; 
     O : float; 
     H : float; 
     L : float; 
     C : float} 
member x.HiLoCheck() = if x.H > x.L then true else false 

같은

거친 원래 DU + 목록 버전을 사용하여 응답의 스케치 - 필수 요소가 목록에없는 경우 오류를 줄 것이다 그러나 이것은 고정 할 수 있습니다 tryFind 대신 find

let checkhilo l = 
    let high = l |> List.find (function |H(_) -> true |_ -> false) 
    let low = l |> List.find (function |L(_) -> true |_ -> false) 
    match high,low with 
    |H(h),L(lo) -> if h>lo then true else false 
    |_ -> failwith "shouldn't happen" 
+0

감사합니다! 이것은 내가 원하는대로 작동합니다. 나는 지금 막 시작했기 때문에 차별의 연합과 기록의 차이에 대해 아직 완전히 명확하지 않다. –

+1

@ChrisTarn 가장 큰 차이점은 DU가'A' 또는'B' 일 수 있다는 것입니다. 유닉스 시간의'DateTime'가'int64'로 시간을 가질 수 있다고 말합니다. 반면 레코드는 데이터 콜렉션을 저장하는 작은 클래스. –

+0

@JohnPlamer 감사합니다. Java/C#에서 많은 것을 명확하게 해줍니다. –

관련 문제