F#中模式匹配的问题

时间:2011-02-21 04:42:56

标签: f#

我需要帮助F#中的paternmatching。 我想这样做:

            let y x =
            match x with
            | x.Contains("hi") -> "HELLO"
            | x.Contains("hello") -> "HI"
            | x -> x

但它不起作用。怎么了?

3 个答案:

答案 0 :(得分:9)

最简单的方法是在比赛中使用守卫。

let y (x:string) =
  match x with
  | x when x.Contains("hi") -> "HELLO"
  | x when x.Contains("hello") -> "HI"
  | x -> x

答案 1 :(得分:7)

包含方法调用的条件只能写入when后卫,因为pblasucci写道。

如果你想使用一些高级F#功能(例如,如果你需要写很多),那么你可以定义活动模式来检查子串(但如果你只是学习F#,不要担心这个) :

let (|Contains|_|) (what:string) (str:string) = 
  if str.Contains(what) then Some(str) else None

然后你可以编写类似的东西(有趣的是,你也可以使用嵌套模式检查多个单词,但同样的东西可以使用&模式编写):

match "hello world" with
| Contains "hello" (Contains "world" str) -> 
    printfn "%s contains both hello and world!" str
| Contains "hello" str -> 
    printfn "%s contains only hello!" str
| _ -> ()

答案 2 :(得分:5)

我认为我对前一个问题的回答here可能会帮助您更好地理解模式匹配。

然而,对于你想要做的事情,我可能会坚持使用简单的if / then / else表达式:

let y x =
  if x.Contains("hi") then "HELLO"
  elif x.Contains("hello") then "HI"
  else x

创建一个特殊的Contains活动模式,如@Tomas Petricek节目也是一个选项,但我发现如果我真的要做一些严肃的字符串模式匹配,那么我只是坚持一对忠实的正则表达式活跃模式:

open System.Text.RegularExpressions

///Match the pattern using a cached interpreted Regex
let (|InterpretedMatch|_|) pattern input =
    if input = null then None
    else
        let m = Regex.Match(input, pattern)
        if m.Success then Some [for x in m.Groups -> x]
        else None

///Match the pattern using a cached compiled Regex
let (|CompiledMatch|_|) pattern input =
    if input = null then None
    else
        let m = Regex.Match(input, pattern, RegexOptions.Compiled)
        if m.Success then Some [for x in m.Groups -> x]
        else None

对于这个问题,请像这样使用它们:

let y = function // shorthand for let y x = match x with ...
    | CompiledMatch @"hi" _ -> "HELLO"
    | CompiledMatch @"hello" _ -> "HI"
    | x -> x

我喜欢这个,因为它很容易涵盖Contains,StartsWith,EndsWith,Equals等等:

let y = function
    | CompiledMatch @"^hi$" _ -> "Equals"
    | CompiledMatch @"^hi" _ -> "StartsWith"
    | CompiledMatch @"hi$" _ -> "EndsWith"
    | CompiledMatch @"leadinghiending" _ -> "Beyond"
    | CompiledMatch @"hi" _ -> "Contains"
    | x -> x

(请注意,由@引入的文字字符串实际上并不需要任何这些正则表达式示例,但作为习惯问题,我总是使用它们,因为您经常需要它们而不是正则表达式。)< / p>