高階関数とは「高度で難解な関数」ではなく、単に引数に関数をとれる関数のことだ。引数に関数をとるというと難しそうに見えるが、次の map という関数の動作を見てみると、結構わかりやすい事が分かる。
map 関数がすることは、[1,2,3,4] のようなリストの各要素のそれぞれに同じ演算を加える操作だ。map は第1引数として、各要素に加えたい演算の関数をとり、第2引数にリストをとる。こういうふうに文章で書くとややこしいが、たとえば、リストの要素をすべて2倍にしたいようなときは次のようにする。 Main> map (* 2) [1,2,3,4,5] [2,4,6,8,10] 上の式で、(*2) というのが、要素を2倍にするという関数だ。それでは2乗にしたいときはどうだろうか、 Main> map (^ 2) [1,2,3,4,5] [1,4,9,16,25] のようなやり方もできるが、自前の関数を作ってmapに渡してみよう。渡すのは f(x) = x * x という関数だ。この関数は x という変数を持ち値 x * x を返す。この fx をHaskell風にラムダ記法で表現すると、 (\x -> x * x) となる。これを map に渡してやればいいのだ。 Main> map (\x -> x * x) [1,2,3,4,5] [1,4,9,16,25] map 以外の高階関数で分かりやすいのに、filter がある。filter の第1引数に関数を渡すと、その関数がTrueを返す要素を選別してリストにしてくれる。たとえば、奇数を取り出したいときは、 Main> filter odd [1,2,3,4,5] [1,3,5] 偶数を取り出したいときは、 Main> filter even [1,2,3,4,5] [2,4] 3より大きい要素を取り出したいときは、 Main> filter (> 3) [1,2,3,4,5] [4,5] このように高階関数を使えば、ループも分岐も記述せずに、リストを加工できる。やらせたいことを関数の形で map や filter などの高階関数の引数として渡してやればいいだけだからだ。むしろ、こちらのほうが、頭のなかの直観的なアイディアをそのまま表現できる。高階関数は「高度で難解」どころか、「高度に理解しやすい」関数なのだ。 追記 map のような高階関数は決してブラックボックスではなく、高階関数はユーザーが普通に定義できる。自前の map 関数 mymap を次のように定義したが、きちんと動作する。 Prelude> :set +m Prelude> let Prelude| mymap f [] = [] Prelude| mymap f (x:xs) = f x : mymap f xs Prelude| Prelude> mymap (^2) [1..5] [1,4,9,16,25] Haskell では関数も first order values なので上のプログラムのようなものも普通に書ける。また、コンパイルは単に(数学的な)式の展開をしているだけなので、プログラムのコンパイルが成功すれば、その関数はきちんと動作することが証明される。
by tnomura9
| 2009-08-06 12:56
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||