F# pattern match directly against let binding

前端 未结 4 450
不知归路
不知归路 2021-01-18 22:39

Is it possible in F# to pattern match directly against a let binding?

For example, this compiles without any warnings:

    let value = 
        match         


        
4条回答
  •  迷失自我
    2021-01-18 22:55

    The reason you're getting that error is because of what F# is doing when you use a variable name in the pattern clause of a match expression.

    Let's say I have

    match arg with
    | x when x = 0 -> "zero"
    | y when y = 1 -> "one"
    | _ -> "other"
    

    I think it's key here to note that, despite not defining x or y prior to the match, this code will still work. This is because x and y are just short codes which makes writing match expressions easier. Behind the scenes, the F# compiler is actually converting that x when x = 0 into "let binding" where x is bound to arg. x can then be used in the x = 0 expression and in the expression after the ->.

    Going back to the problem you ran into:

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

    The reason this won't work, is because in the match expression, F# is rebinding key1 to the value of arg, so key1 -> "value1" is equivalent toif arg1 = arg1 then "value1". The first pattern will always be matched; so, key2 and _ will never be reached.

    I'm not sure how clear my explanation is, so I'll also throw in a second approach to explaining what's happened:

    if you translate the match expression into an if-else it would look like this:

    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"
    

    (why yes, F# will let you throw let bindings into if expressions)

    This if/else expression is equivalent to your match expression. In this form it becomes clear that the first condition will always evaluate to true.

    I won't put it in here, but it may help to look at the code quotation of a match expression. I didn't really get what was going on with match expressions until I saw what the abstract syntax tree they generated looked like.

提交回复
热议问题