関数

【Haskell】関数合成演算子 . の使い方

【Haskell】関数合成演算子の使い方

Haskellの関数合成演算子.の使い方を解説します。

関数合成

Haskellは、純粋関数型プログラミング言語のひとつです。Haskellでのプログラミングでは関数が中心となります。関数型プログラミング言語では「関数合成」について十分に理解しておくことが大切になります。

関数合成とは、複数の関数を組み合わせて新しい関数を作成する強力な手法です。Haskellでは、この関数合成をする際の便利な演算子として関数合成演算子「.」が用意されています。

この記事では、Haskellの関数合成演算子.の使い方を紹介します。

関数合成演算子.とは

関数合成演算子.の基本的な概念と型シグネチャについて説明していきます。関数合成演算子.の型シグネチャは以下のようになります。

ghci> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

これは、関数合成演算子である.が関数(b->c)と関数(a->b)と引数aを取り、結果cを返すことを示しています。文章にすると少しわかりにくいかもしれませんが、絵にすると以下のようになります。

Haskell 関数合成

入力となる引数の型aを型シグネチャが(a->b)である関数Aが受け取り型bに変換します。その後に型シグネチャが(b->c)である関数Bが型bの入力を受け取り、型cの結果に変換するという流れです。この関数を順番に適用していく流れを関数と関数合成演算子を用いることで(B . A)と表現することが可能になります。

基本的な使い方

関数合成演算子.の使い方の例を見てみましょう。例として、文字を大文字に変換して、ASCIIコードに変換するような関数を考えてみます。

import Data.Char

-- 文字列の各文字を大文字に変換後、ASCIIコードに変換する
toUpperAscii :: Char -> Int
toUpperAscii = ord . toUpper
ghci> toUpperAscii 'a'
65

この例では、toUpper関数とord関数を関数合成で合成することで新しくtoUpperAsciiという関数を作成しています。

この例は、概要説明における図で説明した内容に当てはめてみると、関数A=toUpper、関数B=ord、引数a='a'、結果c=65に該当します。絵に当てはめてみると関数合成がどういった動きをしているかをつかんでもらえるのではないかなと思います。

このように既存の関数を組み合わせて新しい関数を簡単に合成して作成できる機能は非常に強力です。

関数合成の利点と注意点

関数合成を利用することの最大の利点は、コードの簡潔性と可読性を高めることができることです。複数の処理を1つの流れで表現できるため、処理の流れが直感的に理解しやすくなります。

例えば、以下の関数はリストの各要素に複数の関数を適用するような場合です。

-- 文字列の各文字を各文字を大文字に変換して、ASCIIコードのリスト変換
stringToUpperAscii :: [Char] -> [Int]
stringToUpperAscii = map (ord . toUpper)
ghci> stringToUpperAscii "haskell"
[72,65,83,75,69,76,76]

関数合成とmap関数をうまく使うことで非常にスマートにコーディングを行うことが可能となります。なお、map関数については「map関数の基本的な使い方」で紹介しているので参考にしてください。

上記のように関数合成は、非常に強力な機能です。ただし、過度に使用すると逆にコードが読みにくくなってしまうことがあります。特に合成する関数が多くなるほど、どの関数が何をしているのかが一見して分かりにくいということもあります。このため、適切なコメントや適切な関数の命名が重要になってきます。

まとめ

Haskellの関数合成演算子.の使い方を解説しました。

関数合成は、複数の関数を組み合わせて新しい関数を作成する強力な手法です。Haskellでは、この関数合成をする際の便利な演算子として関数合成演算子「.」が用意されています。

この記事では、Haskellの関数合成演算子.の使い方を簡単な例を用いて説明しました。関数合成演算子.を使用することで、コードの簡潔性を保ちつつ、複数の関数を効率的に組み合わせることができるようになります。

この記事で紹介した技術を活用し、よりクリーンで効率的なコードを書けるようになってもらえたらと思います。