この章では、Haskellの関数とは何かということを説明をしています。関数の実際例は、 「選択」 「反復」 「ラムダ」で詳しく説明しています。
main が定義されていないソースファイルを、ghc でコンパイルすると、次のようなエラーが出ます。
The IO action ‘main’ is not defined in module ‘Main’
「Main」モジュールの中に、「main」IOアクションが定義されていません、という意味です。
Mainモジュールになります。Mainモジュール中には、main IOアクションを定義しなければなりません。main は、プログラムのスタート地点になることが決まっている特別な変数です。IOアクションとは、IOモナドのアクションです。IOモナドが処理できる副作用とは、入出力そのもののことです。なお、ghci でソースファイルを実行する場合は、ソースファイルの中に main が定義されていなくても、仮想的に main があるものとして実行されます。
Haskellでは、変数にも式を束縛できます。つまり変数も関数のように何かの処理をして値を返せるわけです。そこでHakellでは、引数を受け取る識別子を関数、引数を受け取らない識別子を変数として区別しています。main は、引数を受け取らない変数となりです。
基本的には変数と同じです。引数を追加する点だけが違います。
Haskellは純粋関数型言語で、その関数は、同じ値の引数を与えた場合、その戻り値はいつの場合も同じ値であることが保証されています。そして、それ以外のことは何もしません。このような性質のことを参照透過性と言います。
一方で、ディスプレイで表示される文字列を変更することなどを副作用と呼びます。
Hakellでは、参照透過性を守りながら、副作用にも対応するために、モナドという型クラスを作りました。モナドは参照透過性を守った値と、副作用を行う処理という二つ内容を内包しています。
識別子に引数を与えて関数にするには、次のように記述します。
plusOne x = x + 1
main = print ( plusOne 100 )
実行するには、ghci にファイルを読み込んで、main と入力します。
*Main> main
101
*Main>
ghc でコンパイルしてから実行するには、次のよう入力してください。ここではファイル名が plusOne.hs であることにします。ghci を起動していた場合は、:qで ghci を終了させてください。
ghc plusOne.hs
[1 of 1] Compiling Main ( pulusOne.hs, plusOne.o )
Linking plusOne ...
./plusOne
101
2つの引数を取る関数は、通常「関数名 引数1 引数2」と記述します。しかし、バッククォート
` を使うことによって、「引数1 `関数名` 引数2」
と記述できるようになります。このように2つの値 (引数 )
の間にある演算子のことを中値演算子と呼びます。
add x y = x + y
main = do
print $ add 100 50
print $ 100 `add` 50
*Main> main
150
150
*Main>
演算子を関数のように使うこともできます、中値演算子を式の先頭に移動して括弧 ( ) で囲みます。
main = do
print $ 100 + 50
print $ (+) 100 50
実行結果は先ほどと同じです。