Binding new values in a function to names (identifiers) that are already named?

StackOverflow https://stackoverflow.com/questions/19646014

  •  01-07-2022
  •  | 
  •  

문제

In the book "Expert F# 3.0", there is a text-parsing example to 'lex' and 'parse' polynomial expressions. I was trying to understand it a bit (there was no explanation for the code written) and I came across functions such as this:

let parseIndex src =
    match tryToken src with
        | Some(Hat,src) ->
            match tryToken src with
            | Some(Int num,src) -> (num,src)
            | _ -> failwith "expected an int after ^"
        | _ -> (1,src)

which uses the function

let tryToken (src:TokenStream) = 
    match src with 
    | head::rest -> Some(head, rest)
    | _ -> None

the function parseIndex uses the parameter src and as the code progresses by using tryToken multiple times,every time, the returned src is somehow something else but the function still uses that name!

my question is: what is parseIndex really doing here with src? because on the second pattern-matching, it uses src as if it was a deffirent value given by tryToken, but looking at tryToken, I see that it should give the same result on every use with pattern-matching.

the Hat and Int you see are union cases of Token, as type TokenStream = Token list

도움이 되었습니까?

해결책 2

Later bindings shadow, or hide, earlier bindings. You can bind x as many times as you like:

let x = 1
let x = 2
let x = 3
...

The remainder of the scope will only see the last one.

다른 팁

As Daniel says, this is called shadowing.

It's actually really useful in many situations; imagine this C# function:

public void DoStuff(string s)
{
    var trimmed = s.Trim();

    // For the rest of this function, we should use trimmed, but s is
    // sadly still in scope :( 
}

Shadowing can fix this issue by hiding the original variable:

let DoStuff s =
    let s = s.Trim()
    // Only one 's' is in scope here, and it's trimmed
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top