1

我刚刚开始玩 F# 并创建了以下玩具问题。我已经尝试了多种语法来做到这一点,但似乎无法做到正确。

我有以下类型

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(13210.0);
    ]  

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

我想添加一个新成员来检查高点是否大于或等于低点。如果尝试了各种模式匹配,但似乎无法做到这一点。下面的代码不正确,但足以证明我正在尝试做的事情。

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

我想我需要把它分解成一个元组,但这仍然超出了我非常有限的 f# 经验。

4

1 回答 1

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"
于 2013-06-25T06:21:56.360 回答