模式匹配多个变量

时间:2014-03-13 13:27:51

标签: f# pattern-matching tuples

我是F#的新手,并没有在任何地方看到如何正确地执行以下操作

let fun1 a b =
match a b with
| a + b > 0 -> fun2
| a + b < 0 -> fun3

我必须使用模式匹配来做家庭作业 - 但我不知道如何正确地做到这一点。我以为我可以使用如下元组:

let fun1 (a,b) =
match (a,b) with
| (a,b) when a + b > 0 -> fun2
| (a,b) when a + b < 0 -> fun3

但这也行不通。我该怎么办?

3 个答案:

答案 0 :(得分:12)

你有正确的想法,你忘记了缩进在F#中很重要。添加空格使您可以解决方案:

let fun1 (a,b) =  
    match (a,b) with
    | (a,b) when a + b > 0 -> fun2
    | (a,b) when a + b < 0 -> fun3

这实际上模式匹配两次,所以我们可能想要重写它:

let fun1 t = function 
    | (a,b) when a + b > 0 -> fun2
    | (a,b) when a + b < 0 -> fun3

编译器/解释器将允许这样做,但带有警告:

  

警告FS0025:此表达式上的不完整模式匹配。

我将把它作为一项练习摆脱: - )

PS。很高兴你能够提前做好这项工作。

答案 1 :(得分:9)

SørenDebois是对的。以下是其他几点说明:

  1. ab已经在范围内,因此您无需与它们匹配,您可以匹配任何内容:

    let fun1 (a,b) =
        match () with
        | () when a + b > 0 -> fun2
        | () when a + b < 0 -> fun3
    
  2. 因此,使用if语句可能更惯用。

  3. a + b = 0时你明显错过了这个案例。请注意,编译器始终假定when子句可能不包含任何内容,因此即使添加| () when a + b = 0 -> ...个案,您仍会收到一些警告,即某些情况可能无法处理;您需要改为| () -> ...| _ -> ...

  4. let f <pattern> = match <same pattern> with |...形式的定义有一个内置快捷方式,即let f = function |...。你会像以下一样使用它:

    let fun1 = function
    | (a,b) when a + b > 0 -> fun2
    | ...
    

    请注意,现在ab不受函数定义的约束,因此我的第一个注释中的想法不适用,您必须在模式中引入它们。

答案 2 :(得分:2)

您可以添加匹配子句:

let fun2() = ()
let fun3() = ()
let fun1 a b =
    match (a+b) with
        | res when res > 0 -> fun2
        | res when res < 0 -> fun3
        | _ -> raise (new System.NotImplementedException())

涵盖所有模式的情况,作为良好做法: - )