F#与参数匹配的模式

stt*_*106 4 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 "impossible"
Run Code Online (Sandbox Code Playgroud)

同样的事情:

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"
Run Code Online (Sandbox Code Playgroud)

那么为什么它不匹配nm直接在这里?

Mar*_*ann 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"
Run Code Online (Sandbox Code Playgroud)

符号x将填充i匹配成功的值,然后可在右侧使用->.这个匹配总是成功,这解释了为什么其他匹配案例无法访问.

在您的情况下,恰好您已经命名了匹配变量n,该变量与输入参数的名称相同.

但是,它的价值并不相同.取而代之的是,什么情况是,一个新的值,也称 n正在创建,而以前n是无法再访问.

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

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

let foo n =
    let n = 1
    n
Run Code Online (Sandbox Code Playgroud)

用法示例:

> foo 42;;
val it : int = 1
> foo 1337;;
val it : int = 1
Run Code Online (Sandbox Code Playgroud)

如您所见,let-bound n阴影输入参数n.

OP中的第二个示例,您匹配的n是第一个的变体,因此相同的解释适用.