3

私は F# のさまざまな部分に頭を悩ませようとしてきました (私は C# のバックグラウンドを持っています)、そしてパーサーに興味を持ったので、F# パーサー コンビネーターに関する次のブログ記事に飛びつきました。

http://santialbo.com/blog/2013/03/24/introduction-to-parser-combinators

ここにあるサンプルの 1 つは次のとおりです。

/// If the stream starts with c, returns Success, otherwise returns Failure
let CharParser (c: char) : Parser<char> =
    let p stream =
        match stream with
        | x::xs when x = c -> Success(x, xs)
        | _ -> Failure
    in p               //what does this mean?

しかし、このコードについて私を混乱させたものの 1 つは、in pステートメントです。inMSDNドキュメントでキーワードを調べました:

http://msdn.microsoft.com/en-us/library/dd233249.aspx

私はまた、この以前の質問を見つけました:

F# におけるキーワード "in" の意味

どちらも同じ使い方ではないようでした。適合するように見える唯一のことは、これがパイプライン構造であることです。

4

2 に答える 2

8

を使用すると、expr で使用できる変数のlet x = ... in exprバインドを宣言できます。x

この場合p、 は引数を取り、一致の結果に応じてまたはstreamを返す関数であり、この関数は関数によって返されます。SuccessFailureCharParser

F#ライト構文はバインディングを自動的にネストlet .. inするため、たとえば

let x = 1
let y = x + 2
y * z

と同じです

let x = 1 in
let y = x + 2 in
y * z

したがって、inここでは は必要なく、関数は次のように単純に記述できます。

let CharParser (c: char) : Parser<char> =
    let p stream =
        match stream with
        | x::xs when x = c -> Success(x, xs)
        | _ -> Failure
    p
于 2013-03-31T09:58:55.503 に答える
8

Lee からの回答で問題が説明されます。F# では、inキーワードは、F# に影響を与え、F# を必要とした以前の関数型言語、つまり ML と OCaml からの遺産です。

F# でまだ必要な状況が 1 つだけあることを追加する価値があるかもしれません。つまり、 1 行に式inを記述したい場合です。例えば:let

let a = 10
if (let x = a * a in x = 100) then printfn "Ok"

これは少しファンキーなコーディング スタイルであり、通常は使用しませんが、inこのように書きたい場合は必要です。ただし、いつでもそれを複数の行に分割できます。

let a = 10
if ( let x = a * a
     x = 100 ) then printfn "Ok"
于 2013-03-31T11:40:57.823 に答える