関数
From HaskellWiki
数学的に言えば、関数というのはAという集合のすべての値をBという値の集合に関連付けるものです。関数
はxが整数なら、整数の集合の中にある全ての要素を他の集合--この場合整数の2乗の集合に対応させます。Haskellの関数は以下の例で表されます。付属的に type specification がコンパイラ(や利用しようとするプログラマ)に関数の使い方のヒントを与えます。
Contents |
1 Examples
square :: Int -> Int square x = x * x
言い換えれば、関数というのは "入力" と "出力" を持っていて、入力からどのように出力を生成するかを記述したものといえます。関数は "適用する" ことができます。つまり単純に入力値を関数の引数として与えて、対応する出力値として受け取るということです。
Haskellの関数は "ファーストクラス" エンティティです。つまり
- 名前が与えられる
- ある式の値である
- リストのメンバになれる
- タプルの要素になれる
- 関数の引数として与えられる
- 関数の結果として返される
(Davieの "Introduction to Functional Programming Systems using Haskell."より引用)
1.1 map の例
map
ファーストクラス関数の威力を見られる例として、"map"関数を考えてみましょう。 map:
map :: (a -> b) -> [a] -> [b] map f xs = [f x | x <- xs]
(これはHigher order functionであることを覚えていてください)
この関数は2つの引数をとります:"f"という"a"から"b"へ写像する関数と、"a"のリスト"xs"です。返り値は"b"のリストで、これは"xs"の中のすべての要素に"f"を適用した結果のリストになります。したがって、map square [1,1,2,3,5,8]
[1,1,4,9,25,64]
insert :: Int -> Set -> Set
map insert myList
map insert [1,2,3]
[(insert 1) (insert 2) (insert3)]
1.2 合成 / 畳み込みの例
HaskellではFunction composition演算子をサポートしています:
(.) :: (b -> c) -> (a ->b) -> (a->c) (f . g) x = f (g x)
((insert 1) . (insert 2) . (insert 3)) mySet<hask>は<hask> insert 1 (insert 2 (inesrt 3 mySet))
map insert myList<hask>のそれぞれの要素の間におくことです。Haskellではそれを可能にするコードがあります。それが"畳み込み(folding)"として知られているものです。
"fold"関数はいくつかの種類がありますが、基本的な概念としては同じです。関数とリストが与えられて、リストのすべての要素の"間に"関数を適応させてリストを"折り畳む"イメージです。簡単な二項演算子で考えてみるのが一番簡単ですが、実際使うときは他の関数でもなんら代わりはありません。たとえば<hask>foldr1 (+) [1,1,2,3,5]
"fold"関数はいくつかの種類がありますが、基本的な概念としては同じです。関数とリストが与えられて、リストのすべての要素の"間に"関数を適応させてリストを"折り畳む"イメージです。簡単な二項演算子で考えてみるのが一番簡単ですが、実際使うときは他の関数でもなんら代わりはありません。たとえば<hask>foldr1 (+) [1,1,2,3,5]
1+1+2+3+5
foldr1 (.) (map insert myList)
Set -> Set
newSet = (foldr1 (.) (map insert myList)) mySet
は"newSet"を"mySet"に"myList"の要素が挿入されたものとして定義しています。
2 参考
- Functions section in the Gentle Introduction.
Languages: ja
