ようこそ。睡眠不足なプログラマのチラ裏です。

Haskellのお勉強 その3

高階関数(higher order function)

高階関数とは、プログラミング言語において、関数を引数としたり、
あるいは関数を戻り値とするような関数のことである。
関数型プログラミング言語Haskellにおいては、まず「関数」という値があり、
関数名はそれに束縛された変数であると考えると、理解しやすい。

square n = n * n
map square [1,2,3,4,5]

上記のような場合、map関数は、リスト[1,2,3,4,5]の各要素に、
square関数を適用したリストを返します。つまりこの式の値は
[(square 1),(square 2),(square 3),(square 4),(square 5)]を表し、
これはつまり、[1,4,9,16,25]ということになる。

{-map関数の型-}
map :: (a -> b) -> [a] -> [b]

map関数の型は、第1引数の型が(a -> b)で、第2引数の型が[a]、戻り値が[b]。
第1引数の型(a -> b)は、a型を引数にとり、b型を返す関数。つまり、これを一般化すると、
「map f xs」は、リストxsの各要素xに関数fを適用したリストを返す式と言える。


if式

Haskellでも一般的なプログラム言語と同様に、if文を使える。
.NETと同じように、条件式の値は、真偽値(True or False)でなければならない。
条件式の値が真偽値ではなく、整数値や文字列である場合は型エラーが起こる。


下記は、高階関数mapを用いて、tab文字を@に変換し出力するプログラム。

{-expand0-}
main = do cs <- getContents
          putStr $ expand cs

expand :: String -> String
expand cs = map translate cs

translate :: Char -> Char
translate c = if (==)c '\t' then '@' 
                           else c


上記プログラムにある、「==」演算子は、二項演算子のように使えるが、これも実は関数である。
二項演算子として使える関数は、(==)と括弧でくくったものが関数名となる。
つまり、「x == y 」は「(==) x y」のシンタックスシュガー(糖衣構文)と言える。
もっと言えば、「Haskellには2つ以上の引数を取る関数は存在しない」ので
「x == y 」は、「(((==) x) y)」のシンタックスシュガーって言えるんじゃないかな。

.NETやJavaにおいては、値が等しいかを示す尺度として、
オブジェクトとして同一のものであるかを表す「同一性」と、
値の内容が同じであることを表す「同値性」があるが、
Haskellにおいては、同値性しか表現されない。したがって、(==)関数も
内容の等しさを判定する関数であり、Haskellでは同一であることを調べる手段は存在しない。