有没有办法不必在模式匹配中重复此函数调用?

时间:2015-10-22 14:06:29

标签: f#

我有一个字符串,我想使用一个活动模式来匹配。 我注意到当值是函数的输入时,我必须重复相同的函数调用。有没有办法不必继续调用函数?

let (|A|B|C|X|) stringValue =
        match stringValue with
        | value when compareCaseInsensitive stringValue "a" -> A
        | value when compareCaseInsensitive stringValue "b" -> B
        | value when compareCaseInsensitive stringValue "c" -> C
        | _ -> X stringValue

4 个答案:

答案 0 :(得分:10)

您可以为黑匣子功能定义另一种活动模式:

let (|CCI|_|) (v: string) c =
    if v.Equals(c, System.StringComparison.InvariantCultureIgnoreCase) then Some()
    else None

let (|A|B|C|X|) stringValue =
        match stringValue with
        | CCI "a" -> A
        | CCI "b" -> B
        | CCI "c" -> C
        | _ -> X stringValue

答案 1 :(得分:5)

您似乎正试图强制进行模式匹配,但这并非最适合。您尝试强制进行模式匹配的一个很好的指标是模式匹配中的大量条件检查(在这种情况下,您实际上并没有进行任何模式匹配!)。

let (|A|B|C|X|) stringValue =
        let compareValue = compareCaseInsensitive stringValue
        if compareValue "a" then A
        elif compareValue "b" then B
        elif compareValue "c" then C
        else X stringValue

答案 2 :(得分:5)

对于给出的问题,我会回答 mydogisbox 建议的答案,但是如果这个问题是更复杂的实际问题的替身,或者那么&#39 ; 必须使用模式匹配的其他原因,您可以这样做:

let (|A|B|C|X|) stringValue =
    let compare x = compareCaseInsensitive stringValue x
    match List.map compare ["a"; "b"; "c"] with
    | [true; _; _] -> A
    | [_; true; _] -> B
    | [_; _; true] -> C
    | _ -> X stringValue

这肯定是不是我在问题发布时使用的技术,但如果存在更复杂的潜在问题,它可能会激发解决方案。< / p>

答案 3 :(得分:4)

let (|A|B|C|X|) (stringValue: string) =
        match stringValue.ToLower() with // or your custom toLowerCase function
        | "a" -> A
        | "b" -> B
        | "c" -> C
        | _ -> X stringValue