情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

F#入門(6)識別子について2/スコープ

F#では値も関数も同じものと見做されるので、関数を識別子に結び付けることができます。

関数を識別子に結び付ける方法は値を識別子に結び付ける方法と似ていますが少し違います。

例えば、2つの引数を取ってその和を返す関数は次のようになります。

let summation a b = a + b

値を識別子に結び付ける場合と同じように、関数を識別子に結び付ける場合もletキーワードを使います。letキーワードの後に関数名となる識別子をまず置き、続けて引数となる任意個の識別子を置きます。その後に等号を書き、最後に関数の中身を記述します。引数も全て識別子になることに注意してください。

関数が1行の場合は、等号の後に書いた式(関数の内容)の値がそのまま関数の返す値になります。returnを使う必要はありません。

関数が複数行に亘る場合は、次のような書き方をします。

let heikin a b =

    printfn "heikintiwokeisansimasu"

    let wa = a + b

    let heikin = wa / 2

    printfn "%d to %d noheikinha %d desu" a b heikin

    heikin

これは2つの引数を取ってその平均を返す関数です(int型を取ってint型を返すので答えがおかしいですが)。

まずメッセージを表示し、2つの引数の和を計算しその値を識別子waに結び付けています。

その後、識別子waを2で割りその値を識別子heikinnに結び付け、結果を表示します。

最後に、計算された平均値を返しています。

複数行に亘る関数は、このように関数の内容を1字以上の字下げをして記述します。何字でも問題ありませんが普通は4字字下げします。

また、関数の最後の行の値が、関数の返す値になります。この場合もreturnは必要ありません。

識別子(と型)にはスコープがあります。

スコープ(scope)とはある識別子が定義された場合に、その識別子が有効な範囲のことで、スコープの外で識別子を参照することはできません。参照しようとするとエラーが発生します。

トップレベルの場合は、識別子が定義された後からソースファイルの終わりまでです。関数の場合は、識別子が定義された後から関数の終わりまでです。

なので、上のheikin関数内の識別子waや識別子heikinは、トップレベルから参照できません。

識別子waを参照しようとするとエラーが発生します。

let heikin a b =

    printfn "heikintiwokeisansimasu"

    let wa = a + b

    let heikin = wa / 2

    printfn "%d to %d noheikinha %d desu" a b heikin

    heikin

printfn "wa = %d" wa

識別子heikinの場合は事情が異なります。

この場合、2数の平均値を求める関数に結び付けられた識別子heikinがトップレベルで、また平均値に結び付けられた識別子heikinが関数内でそれぞれ定義されています。

このように、複数のスコープで複数の識別子が定義されている場合にあるスコープから識別子を参照すると、当該スコープに最も近い有効なスコープで定義されている識別子が参照します。

なので、トップレベルで識別子heikinは2数の平均値を求める関数を参照し、上記の関数内で識別子heikinは平均値を参照します。

関数内部で定義された識別子は、トップレベルで定義された識別子とは少し挙動が違います。

関数内部では一度定義された識別子を再定義することができます(これは、値を変更することとは違います。前回書いたようにmutableキーワードを使わない限り値は不変です)。

再定義するというのはもう一度let文を使って識別子に値を結び付けることです。

例えば、次のように。

let f x =

    let x = x * 2

    let x = x + 3

    x

このように、関数内では同じ識別子を何度も定義し直すことができます。

また、識別子はただの名前でしかないので、再定義の際識別子に結び付けられる値の型が変わってもエラーになりません。

例えば、以下のプログラムは正しいF#プログラムです。

let f x =

    let x = x * 2

    let x = x + 3

    let x = (sprintf "kotaeha %d desu” x)

    x

sprintf関数はC言語のsprintf関数と同じでフォーマットと幾つかのデータを取って書式化された文字列を返す関数です。

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-F#