Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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#模式匹配_F#_Pattern Matching - Fatal编程技术网

带参数的F#模式匹配

带参数的F#模式匹配,f#,pattern-matching,F#,Pattern Matching,这可能很简单,但有人能解释为什么下面的模式匹配不合理吗?它说其他规则,例如1,0,将永远不会匹配 let matchTest(n : int) = let ran = new Random() let i = ran.Next(0, 2) match i with | n -> printfn "%i" n | 1 -> printfn "1" | 0 -> printfn "0" | _ -> printfn "

这可能很简单,但有人能解释为什么下面的模式匹配不合理吗?它说其他规则,例如1,0,将永远不会匹配

let matchTest(n : int) = 
    let ran = new Random()
    let i = ran.Next(0, 2)
    match i with
    | n -> printfn "%i" n
    | 1 -> printfn "1"
    | 0 -> printfn "0"
    | _ -> printfn "impossible"
同样的道理:

let matchTest(n : int) = 
    let ran = new Random()
    let i = ran.Next(0, 2)
    let m = n
    match i with
    | m -> printfn "%i" m
    | 1 -> printfn "1"
    | 0 -> printfn "0"
    | _ -> printfn "impossible"
那么为什么不能直接在这里匹配
n
m

| m -> 
具有可匹配任何值的变量
m
。您认为
m

let m = n 
是相同的
m
变量,但不是

因此,剩余的模式将永远不会匹配,因为第一个模式匹配所有输入

你需要一份工作,明白吗


第一个示例中的
n
是一个占位符符号,如果匹配成功,将填充该符号。这和写作是一样的:

let matchTest(n : int) = 
    let ran = new Random()
    let i = ran.Next(0, 2)
    match i with
    | x -> printfn "%i" x
    | 1 -> printfn "1"
    | 0 -> printfn "0"
    | _ -> printfn "impossible"
如果匹配成功,符号
x
将填充
i
的值,然后可在
->
的右侧使用。此匹配始终成功,这解释了为什么无法访问其余的匹配案例

在您的例子中,恰好命名了匹配变量
n
,该变量与输入参数的名称相同

但它的值不一样。相反,发生的情况是,正在创建一个新值,也称为
n
,而以前的
n
不再可访问

这是一种称为“阴影”的语言功能

您还可以在模式匹配之外看到它:

let foo n =
    let n = 1
    n
用法示例:

> foo 42;;
val it : int = 1
> foo 1337;;
val it : int = 1
如您所见,let-bound
n
对输入参数
n
进行了阴影处理


OP中的第二个示例,您在
n
上进行匹配是第一个示例的一个变体,因此同样的解释适用。

如果您将匹配改写为以下内容,您可能会更好地理解它:

let matchTest(n : int) = 
    let ran = new Random()
    ran.Next(0, 2)
    |> function
       | n -> printfn "%i" n
       | 1 -> printfn "1"
       | 0 -> printfn "0"
       | _ -> printfn "impossible"
关键是匹配(或函数)接受一个param,但内部的所有内容都是在最初编写代码时本地声明的。在(外部)n的这一点上不应用闭合

角色

| pattern ->
模式实际上是匹配/函数范围内的“新局部变量”(即lambda),并且与外部的n不同

然后,您需要为这个“新创建的变量”应用guard子句:

另见

或者用例子和你不知道你应该学的东西(最好的意思!)进行详尽的解释


是的,匹配表达式一开始可能会让人困惑。至少对我来说是这样。

我知道如何修复它,但不明白为什么它不能像这样。我想我没有完全理解模式匹配背后发生了什么,我认为这是一个简单的比较,而不是。这真的是阴影吗?而不是真正的范围界定?既然图案是一个lambda?还是我的另一个答案错了?或者阴影和范围/λ是否相同?最后但并非最不重要的一点:我困惑了吗?@Helgereneuroholm我同意阴影绝对是正确的术语。虽然作用域起到了一定的作用,但你并不是完全错误的,如果说关键的方面是嵌套正在进行——记住(搜索轻语法)在F#中,每一行都隐含着一个连接到下一个表达式的

| pattern ->
| pattern when pattern = n -> printfn "%i" n