Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#模式直接匹配let绑定_F#_Pattern Matching_Immutability_Guard Clause - Fatal编程技术网

F#模式直接匹配let绑定

F#模式直接匹配let绑定,f#,pattern-matching,immutability,guard-clause,F#,Pattern Matching,Immutability,Guard Clause,在F#中是否可以直接与let绑定进行模式匹配 例如,编译时不会出现任何警告: let value = match arg with | 1 -> "value1" | 2 -> "value2" | _ -> failwith "key not found" 鉴于以下警告“此规则将永远不会与匹配的key2和行相匹配”: let key1 = 1 let key2 = 2 let

在F#中是否可以直接与let绑定进行模式匹配

例如,编译时不会出现任何警告:

    let value = 
        match arg with
        | 1 -> "value1"
        | 2 -> "value2"
        | _ -> failwith "key not found"
鉴于以下警告“此规则将永远不会与匹配的
key2
行相匹配”:

    let key1 = 1
    let key2 = 2
    let value = 
        match arg with
        | key1 -> "value1"
        | key2 -> "value2"
        | _ -> failwith "key not found"

这是因为尽管let绑定是不可变的,但它们与C#
const
变量不同吗?

只需使用大写字母和
[]
就可以了

let [<Literal>] X = 0
let [<Literal>] Y = 1
let bla arg =
    match arg with
    | X -> "zero"
    | Y -> "one"
    | somethingelse -> somethingelse.ToString()
let[]X=0
设[]Y=1
让布拉阿格=
将arg与
|X->“零”
|Y->“一”
|somethingelse->somethingelse.ToString()

按照惯例,小写名称通常意味着绑定到名称的通配符。

只需使用大写字母和
[]
它们,就可以正常工作

let [<Literal>] X = 0
let [<Literal>] Y = 1
let bla arg =
    match arg with
    | X -> "zero"
    | Y -> "one"
    | somethingelse -> somethingelse.ToString()
let[]X=0
设[]Y=1
让布拉阿格=
将arg与
|X->“零”
|Y->“一”
|somethingelse->somethingelse.ToString()

按惯例,小写名称通常表示绑定到名称的通配符。

如果要在模式匹配的情况下与特定值匹配,则只能使用文字。标识符意味着绑定——即,此模式匹配案例中的实际值将绑定到此案例范围中可见的标识符

正如@DanielFabian所示,您可以定义自己的文本并给它们命名

如果需要匹配的值在编译时未知,可以使用如下保护:

match arg with
| x when x = key1 -> "value1"
| x when x = key2 -> "value2"
| _ -> // etc

有关更多详细信息,请参阅。

如果要在模式匹配案例中与特定值进行匹配,则只能使用文字。标识符意味着绑定——即,此模式匹配案例中的实际值将绑定到此案例范围中可见的标识符

正如@DanielFabian所示,您可以定义自己的文本并给它们命名

如果需要匹配的值在编译时未知,可以使用如下保护:

match arg with
| x when x = key1 -> "value1"
| x when x = key2 -> "value2"
| _ -> // etc

有关更多详细信息,请参阅。

出现该错误的原因是因为F#在匹配表达式的pattern子句中使用变量名时所做的操作

假设我有

match arg with
| x when x = 0 -> "zero"
| y when y = 1 -> "one"
| _ -> "other"
我认为关键是要注意,尽管在匹配之前没有定义x或y,但这段代码仍然有效。这是因为x和y只是短代码,这使得编写匹配表达式更容易。在幕后,当x=0时,F#编译器实际上正在将
x转换为“let binding”,其中
x
绑定到
arg
<然后,可以在
x=0
表达式和
->
后面的表达式中使用code>x

回到您遇到的问题:

let key1 = 1
let key2 = 2
let value = 
    match arg with
    | key1 -> "value1"
    | key2 -> "value2"
    | _ -> failwith "key not found"
这不起作用的原因是,在匹配表达式中,F#正在将
key1
重新绑定到
arg
的值,因此
key1->“value1”等同于
如果arg1=arg1,则为“value1”。第一种模式将始终匹配;因此,
key2
将永远无法访问

我不确定我的解释有多清楚,因此我还将引入第二种方法来解释发生了什么:

如果将匹配表达式转换为if-else,它将如下所示:

let key1 = 1
let key2 = 2

let value = 
    if let key1 = arg in arg = key1 then
        "value1"
    else if let key2 = arg in arg = key2 then
        "value2"
    else
        failwith "key not found"
type Keys=
| Key1
| Key2
match arg with
| Key1 -> "value1"
| Key2 -> "value2"
(为什么是,F#将允许您将let绑定放入if表达式中)

此if/else表达式与匹配表达式等效。在这种形式下,第一个条件的计算结果将始终为真


我不会把它放在这里,但看看匹配表达式的代码引用可能会有所帮助。直到我看到匹配表达式生成的抽象语法树是什么样子,我才真正了解匹配表达式的情况。

之所以会出现这种错误,是因为在匹配表达式的pattern子句中使用变量名时F#所做的事情

假设我有

match arg with
| x when x = 0 -> "zero"
| y when y = 1 -> "one"
| _ -> "other"
我认为关键是要注意,尽管在匹配之前没有定义x或y,但这段代码仍然有效。这是因为x和y只是短代码,这使得编写匹配表达式更容易。在幕后,当x=0时,F#编译器实际上正在将
x转换为“let binding”,其中
x
绑定到
arg
<然后,可以在
x=0
表达式和
->
后面的表达式中使用code>x

回到您遇到的问题:

let key1 = 1
let key2 = 2
let value = 
    match arg with
    | key1 -> "value1"
    | key2 -> "value2"
    | _ -> failwith "key not found"
这不起作用的原因是,在匹配表达式中,F#正在将
key1
重新绑定到
arg
的值,因此
key1->“value1”等同于
如果arg1=arg1,则为“value1”。第一种模式将始终匹配;因此,
key2
将永远无法访问

我不确定我的解释有多清楚,因此我还将引入第二种方法来解释发生了什么:

如果将匹配表达式转换为if-else,它将如下所示:

let key1 = 1
let key2 = 2

let value = 
    if let key1 = arg in arg = key1 then
        "value1"
    else if let key2 = arg in arg = key2 then
        "value2"
    else
        failwith "key not found"
type Keys=
| Key1
| Key2
match arg with
| Key1 -> "value1"
| Key2 -> "value2"
(为什么是,F#将允许您将let绑定放入if表达式中)

此if/else表达式与匹配表达式等效。在这种形式下,第一个条件的计算结果将始终为真


我不会把它放在这里,但看看匹配表达式的代码引用可能会有所帮助。直到看到匹配表达式生成的抽象语法树是什么样子,我才真正了解匹配表达式的情况。

您试图使用的代码提出了两个主要问题

首先,模式匹配:

match arg with
| _ -> "value"
将arg与任何内容匹配,然后返回“value”

将arg与任何内容匹配,将其称为“a”,然后返回“value”。您可以认为匹配有自己的小名称空间,a只存在于匹配中,而匹配只“看到”已在其中命名的内容

其次,如果您想要匹配一组预定义的值,那么您可能需要