識別子(identifier)とは値(value)や関数(function)に付ける名前のようなものです。
C#などの言語では、値を後で参照できるようにその値に適合する型の変数(variable)を宣言してその値を代入し保持しておきますが、F#には変数という概念は存在しません。
代わりに、ある値や関数とある識別子とをletキーワードを使って結び付けます。すると、結び付けられた値や関数は識別子を使って参照することができるようになります。
では、letキーワードを使って値を識別子に結び付けてみます。
値を識別子に結び付ける場合は、letキーワードの後に識別子を指定し、等号を書き、最後に結び付ける値を書きます。ここでの値は、リテラルでなくとも計算式や関数など値を返すものなら何でも構いません。
let文の中で型名を指定していないことに注意してください。
上の一行をF#インタープリタで実行すると、
という結果が返ってきます。
これはxという識別子にint型の値が結び付けられたことを示していますが、明示的にlet文の中で値がint型であることを指定した訳ではありません。F#インタープリタが型を推論してxをint型に決定しています。
以下に値を識別子に結び付ける例を示します。
| let a = 12 let b = 23 let c = a + b printfn "a = %d, b = %d, c = a + b = %d" a b c |

cはaとbの和ですが正しく計算されています。
printfn文で整数を表示する時はフォーマット指定子%dを使います。
| let a = 12 let b = 23.0 let c = a + b printfn "a = %d, b = %f, c = a + b = %d" a b c |
前のプログラムと殆ど同じですが2箇所だけ違うところがあります。2行目でbには23.0というfloat型の値が結び付けられています。また、識別子bはfloat型になるので4行目のprintfnでのフォーマット指定子は%fになります。
上のプログラムは実は正しくありません。これを実行するとエラーが発生します。

エラーメッセージから分かるように、これは3行目でint型の値とfloat型の値を足し算しようとしているためです。F#では異なる型同士の計算はできません。
なので、キャストしてやる必要があります。
| let a = 12 let b = 23.0 let c = a + (int)b printfn "a = %d, b = %f, c = a + b = %d" a b c |
命令型パラダイム言語の変数を説明する際に、メモリの一区画をイメージした「箱」の例えがよく使われますが、識別子は値を格納する箱とは異なるものです。
識別子自体はただの名前で、「箱」自体ではありません。
F#では、一度定義した識別子の値を変えることはできません。
例えば、次のプログラムを実行すると、23ではなく12と表示されます(エラーにはなりません。この場合の"="は代入演算子ではなく比較演算子と解釈されるからです)。
| let x = 12 x = 23 printfn "%d" x |

これは、xが箱ではなく名前(識別子)だからです。単なる名前に値を入れることはできません。
なので、F#では一度識別子を値に結び付けると、その状態を変更することはできないということです(但し、mutableキーワードを使うと変数のように値を変更可能な識別子を作ることができます)。