2016-01-19 87 views
4

这可能很简单,但有人可以解释为什么下面的模式匹配不明智吗?它说其他规则例如1,0,_永远不会匹配。F#模式与参数匹配

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" 

那么,为什么不能与之相匹配nm直接在这里?

回答

6

在第一个例子中的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 

正如你所看到的,让绑定n阴影输入参数n

OP中的第二个例子,您在n上匹配的地方是第一个例子的变体,所以应用相同的解释。

+0

嗯。这真的是影子吗?而不是实际范围?既然模式是lambda?或者是我的其他答案,然后错了?或者是阴影和范围/ lambda相同?最后但并非最不重要的是:我感到困惑吗? –

+1

@HelgeReneUrholm我同意阴影绝对是正确的术语。尽管范围可以发挥作用,并且你并不完全不正确,但建议关键方面是嵌套正在进行 - 记住(在F#中搜索“光语法”),每行都隐含有一个“in”连接它到下一个表达式 –

3

你的第一图案

| m -> 

具有可变m其可匹配任何值。您认为该m

let m = n 

相同m变量,它不是。

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

你需要一个when clause,看到guard

| m when m = n -> 
+0

我知道如何解决它,但不明白为什么它不能这样。我认为我没有完全理解模式匹配背后发生的事情,认为它是简单的比较,它不是。 – stt106

3

如果你重写你的对手是有关以下你也许可以更好地了解它:

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 -> 

图案其实是在匹配/功能范围“新局部变量”(即一个拉姆达)和NOT同一正外部。

然后,您需要申请保护条款对于这种“新创建的变量”:

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

参见https://msdn.microsoft.com/en-us/library/dd233242.aspx

或者详尽的举例说明,哪些是你永远不知道你应该学会(以最好的意思!)在http://fsharpforfunandprofit.com/posts/match-expression/

是的,匹配表达式可能会混淆起初。至少对我来说是这样。