如何在匹配的保护表达式中使用 TryParse?

Rob*_*Rob 2 f# pattern-matching

我构建了一个玩具电子表格来帮助学习 F#。当我处理新单元格的文本时,我将其存储为可识别类型。为了解析它,我觉得我应该能够做类似的事情:

        let cv =
            match t with
            | _ when t.Length=0 -> Empty
            | x when t.[0]='=' -> Expr(x)
            | x when t.[0]='\"' -> Str(x)
            | (true,i) when Int32.TryParse t -> IntValue(i) // nope!
            | _ -> Str(t)
Run Code Online (Sandbox Code Playgroud)

我已经尝试了相当多的组合,但我无法将 TryParse 放在守卫中。我写了一个助手:

let isInt (s:string) = 
    let mutable m:Int64 = 0L
    let (b,m) = Int64.TryParse s
    b
Run Code Online (Sandbox Code Playgroud)

我现在可以写:

|    _ when Utils.isInt t -> IntValue((int)t)  
Run Code Online (Sandbox Code Playgroud)

这似乎是一个糟糕的解决方案,因为它丢弃了转换后的结果。将 TryParse 纳入防护的正确语法是什么?

bri*_*rns 5

我认为活跃模式可以满足您的需求:

let (|Integer|_|) (str: string) =
   let flag, i = Int32.TryParse(str)
   if flag then Some i
   else None

let cv =
    match t with
    | _ when t.Length=0 -> Empty
    | x when t.[0]='=' -> Expr(x)
    | x when t.[0]='\"' -> Str(x)
    | Integer i -> IntValue(i)
    | _ -> Str(t)
Run Code Online (Sandbox Code Playgroud)

但如果你真的想要TryParse处于保护状态(并且你不介意解析两次),你可以这样做:

| x when fst (Int32.TryParse(t)) -> IntValue (Int32.Parse(x))
Run Code Online (Sandbox Code Playgroud)