関数

【Haskell】map関数の基本的な使い方

【Haskell】map関数の基本的な使い方

Haskellでmap関数を使用してリストの各要素に関数を適用する方法を解説します。

map関数による関数適用

map関数は、関数とリストを受け取って、リストの各要素に関数を適用した結果を返す関数です。

このように引数に関数を受け取る関数は、高階関数と言います。高階関数の概要については「高階関数の基本」でまとめているので参考にしてください。map関数は高階関数の中でも代表的な関数であり、関数型プログラミングにおいて中心的な関数の一つです。

本記事では、map関数を使用してリストの各要素に関数を適用する方法を紹介します。

map関数の基本的な使い方

map関数の型シグネチャとしては、以下のようになっています。

map関数
map :: (a -> b) -> [a] -> [b]

上記の型シグネチャの意味は「(a -> b)a型を引数として受け取り、b型を返却する関数」と「[a]a型のリスト」の2つの引数を受け取って、「[b]b型のリスト」を返却する関数ということを意味しています。

簡単に言うと、map関数は第1引数で受け取った関数を第2引数のリストの各要素に適用した結果リストを返却するということになります。具体的な使用例を見ていただくとイメージがつかめると思いますので、以降でいくつかの使用例を使いながらmap関数の使い方を説明します。

型シグネチャの基本については「型シグネチャと型変数の基本」でまとめているので参考にしてください。

map関数の使用例

ここではmap関数の簡単な使用例を使ってイメージをつかんでもらいたいと思います。以下は説明のための簡単な例です。引数に渡す関数を変更することでリストに対して様々な変換をかけることができますので、色々と試してみてください。

すべての要素を2倍にする

リストのすべての要素を2倍にする場合には、map関数を使用して以下のようにします。

-- 全ての要素を2倍にする
doubles :: [Int] -> [Int]
doubles xs = map (*2) xs
【実行結果】
ghci> doubles [1,2,3,4,5]
[2,4,6,8,10]

上記では、2倍する関数(*2)を受け取ったリストの各要素に対して適用します。結果を見ても分かるようにリストの全ての要素が2倍にできていることが分かります。

文字列のリストを大文字にする

リストの文字列を大文字にする場合には、map関数を使用して以下のようにします。ここでは文字(Char)を大文字にするために、Data.ChartoUpper関数をインポートして使用します。

import Data.Char (toUpper)

-- 文字列のリストを大文字にする
toUpperCase :: [String] -> [String]
toUpperCase strs = map (map toUpper) strs
【実行結果】
ghci> toUpperCase ["hello","world"]
["HELLO","WORLD"]

上記例では、map関数を2回適用していることに注意してください。Stringは、Char型のリストのことで[Char]と同じ意味です。(map toUpper)の部分は「Stringの各文字Charに対してtoUpperを適用する関数」で、外側のmapは受け取ったStringリストの各Stringに対して、(map toUpper)関数を適用するということを意味しています。

リスト内の数値を文字列に変換する

リスト内の数値を文字列に変換する場合には、map関数を使用して以下のようにします。文字列にする場合には、show関数を使用します。

-- リスト内の数値を文字列に変換する
toStrings :: [Int] -> [String]
toStrings nums = map show nums
【実行結果】
ghci> toStrings [1,2,3,4,5]  
["1","2","3","4","5"]

上記では、受け取ったリストの各要素のInt型の数値に対して、show関数をかけることで文字列に変換しています。結果を見ると数値が文字列に変換されていることが分かるかと思います。

まとめ

Haskellでmap関数を使用してリストの各要素に関数を適用する方法を解説しました。

map関数は、関数とリストを受け取って、リストの各要素に関数を適用した結果を返す関数で、関数型プログラミングにおいて中心的な高階関数の一つです。簡単な例を用いてmap関数の使用方法を紹介しています。

map関数は非常に基本的で中心的な高階関数なのでぜひ使い方をしっかりと覚えてもらいたいと思います。