束縛

束縛(bind)はletの説明のところで出てきたね。
これは一言では意味を表しにくい言葉なんだ。あえて言うなら、局所的に名前と値を結びつけている場所を示す言葉かな。

ひとまず、letを使ったソースを見てみよう。

module Testlet where

f = let x = 4
    in x + 10

g x = let x = 2
          y = x*3
          z = x+10
      in x*y+z

h x = let a = x
          x = 2
          y = x*3
          z = x+10
      in a*y+z

関数の定義が複数の行にまたがっているけど、関数の本体はinの後の1文だ。
letで括られている文は、関数の本体で使う値を表しているんだ。
一つずつ結果を見ながら説明しよう。

*Testlet> f
14

これは明らかだよね。
わざわざletを使う意味はないけど、説明のためだからね。
xは関数の外では定義されていなかったけど、fの中では使えていることが分かるね。

*Testlet> x

<interactive>:1:0: Not in scope: `x'

xは見つからないって出てくるね。
次にg xだ。

*Testlet> g 0
24
*Testlet> g 1
24

g xのxは結果に反映されていない。
letで新しいxを束縛しているから、g xで代入された値は隠されているのだ。
全く使われていないから、実は何が入っても問題ない。使ってないから意味はないけど。

*Testlet> g "keisan"
24

次はh xである。これはg xとほとんど同じだけれど、xをaで置き換えようとしてみた。

*Testlet> h 0
24
*Testlet> h 1
24

結果はg xと変わらない。let下では順番は関係ないようだ。

実は、というか、前に見た例がそうだけど、インタプリタ上でletを使うと、対話的に値を束縛できる。

*Testlet> pi
3.141592653589793
*Testlet> let pi = 4
*Testlet> pi
4

あまり良い例じゃないけど、piを別の値として使うことが出来る。
関数も定義出来る。

*Testlet> let k x = x + x*x
*Testlet> k 4
20

このインタプリタ上のletは、ソースコード上の剥き出しの定義と同じように使うことが出来る。
実はソースコード上の定義は剥き出しではないけど。
ソースコードの一番始めに書いてある

module Testlet where

これの説明しなければなるまい。
これは、定義が有効になる範囲(スコープ)を表しているんだ。
つまり、今まで関数の定義とか、宣言とか適当に呼んでいたのは束縛だったのだ。
module Xxxが束縛の範囲を表している。
インタプリタで、:moduleとするとPreludeに移動する。
すると、Testletにおいて束縛された値は使えなくなる。

*Testlet> :module
Prelude> f

<interactive>:1:0: Not in scope: `f'

:moduleでTestletに戻ると、ちゃんと使える。

Prelude> :module Testlet
Prelude Testlet> f
14

表示が少し変わったけど、まあいいや。まだ:moduleの使い方が良く分かってないんだよね。
こうやって、束縛する範囲を表すのに、moduleではwhereを使っている。
関数の定義(モジュール下の束縛)にもwhereは使える。

module Testwhere where

f x = x * y
      where y = x + 2

whereはこんな風に後に付ける。
同じ範囲にある束縛は、定義された順番に関係なく使えるから、この書き方で問題ないんだ。

これを、説明のために、:loadで読み込む。
するとこんな感じになる。

Prelude Testlet> :load testwhere.hs
Compiling Testwhere        ( testwhere.hs, interpreted )
Ok, modules loaded: TestWhere.
*Testwhere> f 2
8
*Testwhere> f (h 2)

<interactive>:1:3: Not in scope: `h'

fはTestwhereのものになって、hはTestwhere下で束縛されていないので使えない。

束縛については良く分かっていないので、今回はこのくらいで。

次は、範囲について説明が必要だと思うけど、それはもう少し後で。
入出力に進んでね。

タグ:

+ タグ編集
  • タグ:
最終更新:2007年09月28日 19:44