Chris Tarn
Chris Tarn

Reputation: 629

Adding a member to a Discriminated Union that compares two values of the data type

I have just begun playing with F# and created the following toy problem. I have experimented with a number of syntax to do this but can't seem to get it right.

I have the following type

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

And the following two examples

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

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

I want to add a new member which checks to to see if the high is greater than or equal to the low. If have tried various pattern matchings but can't seem to get this right. The code below is incorrect but will suffice to demonstrate what I'm trying to do.

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

I think I need to break it down into a tuple but that too is still beyond my very limited f# experience.

Upvotes: 1

Views: 111

Answers (1)

John Palmer
John Palmer

Reputation: 25516

I think you actually want to use a record as your data type rather than a list of Discriminated Unions. Otherwise, your first step needs to be finding the H and 'L' elements in your list.

Something like

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

EDIT

rough sketch of answer using the original DU + list version - will give errors if the required elements are not in the list but this can be fixed with tryFind instead of 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"

Upvotes: 3

Related Questions