4

我对 F# 很陌生,我想用 (match ... with ...) 语法比较两个值

当我尝试像这样比较两个值时会出现问题:

let value1 = 19
let isValue1 y =
    match y with
    | value1 -> y + 1
    | _ -> y

我收到一条警告,永远无法到达代码的“| _ -> y”部分。为什么是这样?

我知道我可以执行以下操作以使该功能按我想要的方式工作:

let value1 = 19
let isValue1 y =
    match y with
    | _ when y = value1 -> true
    | _ -> false

这也有效

let value1 = 19
let isValue1 y =
    match y with
    | 19 -> true
    | _ -> false

我只是好奇为什么我不能这样做,以及 match 是如何工作的。

4

3 回答 3

11

match 语句中的 value1 被定义为一个新变量,其值设置为 y(作为匹配项)。上面定义的 value1 将被忽略,就像您在 C# 函数中声明一个与类变量同名的局部变量一样。出于这个原因,第一个匹配条件将匹配所有内容,而不仅仅是先前定义的 value1 值,因此会出现错误。希望澄清问题。

于 2009-01-26T18:15:16.383 回答
6

模式匹配既是一种控制结构(接下来执行什么代码),又是一种绑定结构(如“let”,将名称绑定到值)。所以当你这样做时

match expr with
| name -> ...

模式(“名称”)始终匹配,并且标识符“名称”只是绑定到表达式的值。这就是为什么模式匹配主要用于区分联合(案例类型),您可以根据结构进行匹配。例如

match someOption with
| Some(x) -> ... // binds x
| None -> ...

match someList with
| h :: t -> ... // binds h and t to head/tail
| [] -> ...
于 2009-01-26T18:25:17.457 回答
2

您可以将输入与[<Literal>]属性标记的文字/标识符匹配,而无需绑定它。

例如:

#light
[<Literal>]
let E  = 2.718281828459


let isE x =
    match x with
    | E -> true
    | _ -> false

print_any (isE 3.2)
print_any (isE E)

根据克里斯史密斯的说法

于 2009-02-01T20:48:19.030 回答