2011年12月26日

F#初心者による in キーワドの考察

  
このエントリは、F# Advent Calendar 2011のボーナスステージへの参加記事です。



実は、この記事は、僕のF#専用ブログGushwell's F# Programming Diaryに掲載したものです。
しかし、このブログがアクセス不可状態になってしまったため、今までアップした記事が
すべて閲覧できなくなってしまいました。なんとか、CD-Rへバックアップしたものから、
いくつかの記事の下書きを見つけることができましたので、今回アップするこの記事も、
その下書きをもとに、再度清書し直したものです。

この記事は、僕がF#を学び始めて疑問に思った in についての考察であり、
これからF#学ぼうと思っている方には、それなりに有用な内容になっているのではと勝手に思ってます。

では、本題に入りましょう。


以下のコードを見て下さい。


僕がF#の勉強を始めたころには、この in の意味が全く分かりませんでした。
なので、これからF#を学ぶ人のために、ここで、in キーワードについて
考えてみたいと思います。

さて、上のF#のコードですが、これは、

printfn "%A" x の中だけで、x を使いますよ、その Xは 1 に束縛されていますよ。

という意味になります。

では、


はどうでしょうか。これは、abs関数が値を持つので、


と警告が出てしまいます。
F#では、原則として式の値を捨て去ることができないことを思い出しましょう。

一方、最初に示したコードでは、printfn は、unit型なので、値はありません。
だから最初のコードは問題ありません。

abs を使ったコードに話を戻すと、値を捨て去らないように、
absの返す値を何らかの変数に束縛するなどのコードが必要となります。
そこで、


とzに代入(束縛)するようにしないといけません。
例えば、このコードに続けて、


とzを参照するコードを書くわけですね。書くまでもないが、10 が表示されます。
では、次のコードはどうでしょうか。


このコードの場合、y は、1行目だけの局所変数になっているので、3行目でコンパイルエラーになります。

次のようなコードの場合は、問題ありません。ただしくコンパイルができます。


これから分かることは、in の右側が主であり、in の左側が従だということです。
僕は、let で始まるんだから、y = 10 が主処理であるという感覚から抜け切れなかったため、
in が理解できなかったようです。

では、関数定義を使ったときの in について調べてみます。

まずは、一番簡単な例。


かなり、無理やり感は、否めないけど...
この原型は、


であり、2を局所変数 x に束縛させた例です。つまり、


と同じです。
もう少し、まともな例を書いてみます。


これは、局所[変数]ではなく、局所[関数]を使っていますが、考え方は同じです。
骨格は、


なのですが、このadd関数を局所関数として定義しているということになります。

それでは、僕が、in について調べてみようと思った発端となったコードを見てみます。


いきなりこのコードをみて、inが何を意味しているのかを理解するのは、F#初心者には
結構難しいじゃないかと思います。
少なくとも僕は、理解できませんでした。
しかし、ここまで順に説明を読んできた方には、理解できるんじゃないでしょうか?


が、この式の骨格であり、
引数2つのSumTotal関数は、引数1つのSumTotalの[中]でのみ利用できる局所関数として、
定義しているということです。

これが僕のたどり着いた in の意味です。

なお、ここまで書いておいてなんですが、実際のF#では、複数行に分けた場合、in は
省略できますので、上のコードは、以下のコードと同じです。


それでは最後に、前述した dbl 関数の定義について in を使わないコードに
書きなおしてみます。


これならば、何も悩む必要はないですね。

つまり、ワンライナーを使わなければ、in は不要ということです。
僕は、ワンライナー嫌いなので(単に理解できる頭が無いというだけ?)、
in を使うことは無いと思いますが、
他の人の書いたコードを読む場合は、この in の知識が役に立つと思われます。



 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52211852