<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Haskell｜Haskell Tech</title>
	<atom:link href="https://haskell-tech.nkhn37.net/category/haskell/feed/" rel="self" type="application/rss+xml" />
	<link>https://haskell-tech.nkhn37.net</link>
	<description>Haskell学習サイト</description>
	<lastBuildDate>Thu, 01 Aug 2024 09:08:10 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://haskell-tech.nkhn37.net/wp-content/uploads/2023/12/cropped-lion-normal-clear-32x32.png</url>
	<title>Haskell｜Haskell Tech</title>
	<link>https://haskell-tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【Haskell】関数合成演算子 . の使い方</title>
		<link>https://haskell-tech.nkhn37.net/haskell-function-composition-dot/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-function-composition-dot/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Wed, 31 Jul 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[.]]></category>
		<category><![CDATA[関数合成]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=558</guid>

					<description><![CDATA[Haskellの関数合成演算子.の使い方を解説します。 関数合成 Haskellは、純粋関数型プログラミング言語のひとつです。Haskellでのプログラミングでは関数が中心となります。関数型プログラミング言語では「関数合]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellの<span class="marker"><strong>関数合成演算子<code>.</code>の使い方</strong></span>を解説します。</p>



<h2 class="wp-block-heading">関数合成</h2>



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



<p class="wp-block-paragraph">関数合成とは、複数の関数を組み合わせて新しい関数を作成する強力な手法です。Haskellでは、この関数合成をする際の便利な演算子として関数合成演算子「<span class="marker"><strong><code>.</code></strong></span>」が用意されています。</p>



<p class="wp-block-paragraph">この記事では、<span class="marker"><strong>Haskellの関数合成演算子<code>.</code>の使い方</strong></span>を紹介します。</p>



<h3 class="wp-block-heading">関数合成演算子.とは</h3>



<p class="wp-block-paragraph">関数合成演算子<code>.</code>の基本的な概念と型シグネチャについて説明していきます。関数合成演算子<code>.</code>の型シグネチャは以下のようになります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
ghci&gt; :t (.)
(.) :: (b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; c
</pre></div>


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


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="865" height="220" src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/08/image-1.png" alt="Haskell 関数合成" class="wp-image-566" style="width:468px;height:auto" srcset="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/08/image-1.png 865w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/08/image-1-300x76.png 300w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/08/image-1-768x195.png 768w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/08/image-1.png 856w" sizes="(max-width: 865px) 100vw, 865px" /></figure>
</div>


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



<h3 class="wp-block-heading">基本的な使い方</h3>



<p class="wp-block-paragraph">関数合成演算子.の使い方の例を見てみましょう。例として、文字を大文字に変換して、ASCIIコードに変換するような関数を考えてみます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
import Data.Char

-- 文字列の各文字を大文字に変換後、ASCIIコードに変換する
toUpperAscii :: Char -&gt; Int
toUpperAscii = ord . toUpper
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; toUpperAscii &#039;a&#039;
65
</pre></div>


<p class="wp-block-paragraph">この例では、<code>toUpper</code>関数と<code>ord</code>関数を関数合成で合成することで新しく<code>toUpperAscii</code>という関数を作成しています。</p>



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



<p class="wp-block-paragraph">このように既存の関数を組み合わせて新しい関数を簡単に合成して作成できる機能は非常に強力です。</p>



<h3 class="wp-block-heading">関数合成の利点と注意点</h3>



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



<p class="wp-block-paragraph">例えば、以下の関数はリストの各要素に複数の関数を適用するような場合です。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 文字列の各文字を各文字を大文字に変換して、ASCIIコードのリスト変換
stringToUpperAscii :: &#x5B;Char] -&gt; &#x5B;Int]
stringToUpperAscii = map (ord . toUpper)
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; stringToUpperAscii &quot;haskell&quot;
&#x5B;72,65,83,75,69,76,76]
</pre></div>


<p class="wp-block-paragraph">関数合成と<code>map</code>関数をうまく使うことで非常にスマートにコーディングを行うことが可能となります。なお、<code>map</code>関数については「<a href="https://haskell-tech.nkhn37.net/haskell-map-function-basic/">map関数の基本的な使い方</a>」で紹介しているので参考にしてください。</p>



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



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellの<span class="marker"><strong>関数合成演算子<code>.</code>の使い方</strong></span>を解説しました。</p>



<p class="wp-block-paragraph">関数合成は、複数の関数を組み合わせて新しい関数を作成する強力な手法です。Haskellでは、この関数合成をする際の便利な演算子として関数合成演算子「<span class="marker"><strong><code>.</code></strong></span>」が用意されています。</p>



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



<p class="wp-block-paragraph">この記事で紹介した技術を活用し、よりクリーンで効率的なコードを書けるようになってもらえたらと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-function-composition-dot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】関数適用演算子 $ の使い方</title>
		<link>https://haskell-tech.nkhn37.net/haskell-function-application-dollar/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-function-application-dollar/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 06 Apr 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[$]]></category>
		<category><![CDATA[関数適用]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=545</guid>

					<description><![CDATA[Haskellの関数適用演算子$の使い方を解説します。 関数適用 Haskellは、純粋関数型プログラミング言語のひとつです。Haskellでのプログラミングでは関数が中心となるため、関数を適用するのに便利な機能が用意さ]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellの<span class="marker"><strong>関数適用演算子<code>$</code>の使い方</strong></span>を解説します。</p>



<h2 class="wp-block-heading">関数適用</h2>



<p class="wp-block-paragraph">Haskellは、純粋関数型プログラミング言語のひとつです。Haskellでのプログラミングでは関数が中心となるため、関数を適用するのに便利な機能が用意されています。</p>



<p class="wp-block-paragraph">関数適用とは、簡単に言うと関数に引数を渡して実行することです。Haskellでは、この関数適用をする際の便利な演算子として関数適用演算子「<span class="marker"><strong><code>$</code></strong></span>」が用意されています。</p>



<p class="wp-block-paragraph">この記事では、Haskellの<span class="marker"><strong>関数適用演算子<code>$</code>の使い方</strong></span>を紹介します。</p>



<h3 class="wp-block-heading">関数適用演算子<code>$</code>とは</h3>



<p class="wp-block-paragraph">ここでは、Haskellにおける関数適用演算子<code>$</code>の基本的な概念とその型シグネチャについて詳しく説明します。Haskellでは、通常の関数適用（つまりは関数に引数を適用すること）は空白を使って表されます。例えば、以下のような形です。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
result = f a
</pre></div>


<p class="wp-block-paragraph">上記は、関数<code>f</code>に引数<code>a</code>を適用して結果を<code>result</code>に取得します。しかし、この方法では、複数の関数を適用する場合に、括弧を多用する必要があります。ここで、<span class="marker"><strong>関数適用演算子<code>$</code></strong></span>が役に立ちます。</p>



<p class="wp-block-paragraph"><code>$</code>は、右結合の関数適用演算子で、括弧を使わずに関数適用を表現できます。<code>$</code>の型シグネチャは以下の通りです。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; :t ($)
($) :: (a -&gt; b) -&gt; a -&gt; b
</pre></div>


<p class="wp-block-paragraph">これは、<code>$</code>が関数<code>(a -> b)</code>とその引数<code>a</code>を取り、結果<code>b</code>を返すことを示しています。実際の動きとしては、<code>$</code>はただの関数適用を行いますが、最も低い優先順位を持つため、通常のスペースによる関数適用よりも後に評価されます。</p>



<p class="wp-block-paragraph">例を挙げてみると以下の2つの式は等価となります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 括弧を使って表現
f (g (h x))

-- 関数適用演算子$を使って表現
f $ g $ h x
</pre></div>


<p class="wp-block-paragraph">上記のように複数の関数を順次適用していくような場合に、関数適用演算子$を使うことによって括弧を削減することができ、コードを読みやすく、書きやすくすることができます。</p>



<h3 class="wp-block-heading">基本的な使い方</h3>



<p class="wp-block-paragraph">関数適用演算子$の使い方の例を見てみましょう。以下の2つの式は同じ結果<code>6.0</code>となります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 括弧を使って表現
result1 :: Double
result1 = (+) 1 (sqrt (3^2 + 4^2))

-- 関数適用演算子$を使って表現
result2 :: Double
result2 = (+) 1 $ sqrt $ 3^2 + 4^2
</pre></div>


<p class="wp-block-paragraph">まず、括弧を使用した<code>result1</code>の例では、<code>sqrt (3^2 + 4^2)</code> を先に計算し、その結果に<code>1</code> を加えるために括弧を使っています。括弧は、<code>sqrt</code>関数に<code>3^2 + 4^2</code>の計算結果を適用し、その結果を<code>(+)</code>関数の第2引数として使用するために必要です。</p>



<p class="wp-block-paragraph">一方で、関数適用演算子を使用したresult2の例では、関数適用演算子<code>$</code>を使用しています。<code>$</code>はその右側の式を最初に評価し（この場合は <code>sqrt $ 3^2 + 4^2</code>）、その結果を左側の関数に適用します。</p>



<p class="wp-block-paragraph">ここでの<code>$</code>の利点は、括弧を排除してコードをより読みやすくできる点です。<code>$</code>の使用により「<code>3^2 + 4^2</code>」が最初に計算され、その結果が「<code>sqrt</code>」に適用され、最後に「<code>1</code>を加える <code>(+)</code>関数」にその結果が適用されます。右から順に式を読んでいくと関数の適用の流れを簡単に理解することができます。</p>



<p class="wp-block-paragraph">どちらもHaskellでは有効な式であるため、異なるスタイルを示しているにすぎませんが、Haskellのコミュニティでは、コードの可読性と簡潔性を高めるために、不必要な括弧の使用を避けるスタイルが好まれます。</p>



<p class="wp-block-paragraph">しかし、可読性を維持することが最優先されるべきであり、場合によってはコードの意図を明確にするために括弧を使った方がよいという場合もあります。例えば、複雑な式の一部を明示的にグループ化する場合や演算子の優先順位に混乱が生じるような場合には、括弧を使用して明確にすることが推奨されます。</p>



<p class="wp-block-paragraph">結局のところ、これらのスタイルの適用には適切なバランスが必要です。コードの明瞭さ、維持管理の容易さ、そしてチーム内での一貫性を保つことを意識して使用してください。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellの<span class="marker"><strong>関数適用演算子<code>$</code>の使い方</strong></span>を解説しました。</p>



<p class="wp-block-paragraph">Haskellでは、関数適用をする際の便利な演算子として関数適用演算子「<span class="marker"><strong><code>$</code></strong></span>」が用意されています。<code>$</code>を使用することで不必要な括弧を用いないで簡潔に関数の適用を行うことができます。</p>



<p class="wp-block-paragraph">Haskellでは、簡潔なコードが好まれるため<code>$</code>を使用した関数適用したスタイルは好まれますが、場合によっては括弧による関数適用の方がコードの可読性が高くなる可能性があります。</p>



<p class="wp-block-paragraph">コードの明瞭さ、維持管理の容易さ、そしてチーム内での一貫性を保つことを意識して使用するように注意してみてください。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-function-application-dollar/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】カリー化と部分適用</title>
		<link>https://haskell-tech.nkhn37.net/haskell-currying-partial/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-currying-partial/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Mon, 01 Apr 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[currying]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[カリー化]]></category>
		<category><![CDATA[部分適用]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=518</guid>

					<description><![CDATA[Haskellにおいて高階関数を理解するために重要となる「カリー化(Currying)」と「部分適用 (Partial Application)」について解説します。 カリー化と部分適用 高階関数とは、引数に関数を受けと]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellにおいて高階関数を理解するために重要となる「<span class="marker"><strong>カリー化(Currying)</strong></span>」と「<span class="marker"><strong>部分適用 (Partial Application)</strong></span>」について解説します。</p>



<h2 class="wp-block-heading">カリー化と部分適用</h2>



<p class="wp-block-paragraph"><strong>高階関数</strong>とは、引数に関数を受けとったり、返り値として関数を返却できる関数のことを言います。高階関数は、Haskellのような関数型プログラミング言語では必要不可欠なものとなっています。</p>



<p class="wp-block-paragraph">高階関数について、理解するために覚えておくべき内容として「<span class="marker"><strong>カリー化(Currying)</strong></span>」と「<span class="marker"><strong>部分適用 (Partial Application)</strong></span>」という考え方があります。</p>



<p class="wp-block-paragraph">この記事では、カリー化と部分適用について説明します。</p>



<div class="wp-block-jin-gb-block-box concept-box5">
<p class="wp-block-paragraph">Haskellの関数の基本については「<a href="https://haskell-tech.nkhn37.net/haskell-function-basic/" target="_blank" rel="noreferrer noopener">関数の基本</a>」にまとめているので参考にしてください。</p>
</div>



<h3 class="wp-block-heading">カリー化 (currying)</h3>



<p class="wp-block-paragraph">Haskellは、純粋関数型のプログラミング言語であるため、実装の中心は関数となります。Haskellの関数の基本は「<a href="https://haskell-tech.nkhn37.net/haskell-function-basic/" target="_blank" rel="noreferrer noopener">関数の基本</a>」でまとめているので参考にしてください。</p>



<p class="wp-block-paragraph">この記事で、伝えたいHaskellの関数における重要なポイントの1つは以下になります。</p>



<div class="wp-block-jin-gb-block-box concept-box1">
<p class="wp-block-paragraph"><span class="marker"><strong>Haskellのすべての関数は、引数を1つだけ取る</strong></span></p>
</div>



<p class="wp-block-paragraph">しかし、皆さんが関数を作成する際には、複数の引数をとる関数を作成してきたと思います。これはどういうことでしょうか。実際にはHaskellの関数は「<span class="marker"><strong>カリー化 (Currying)</strong></span>」された関数だったのです。カリー化について理解できると上記の引数を1つだけとるの意味を理解することができます。</p>



<p class="wp-block-paragraph">簡単な例を使って理解していきましょう。例として以下のような2つの整数を加算するような簡単な関数を考えてみましょう。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
add :: Int -&gt; Int -&gt; Int
add x y = x + y
</pre></div>


<p class="wp-block-paragraph">次の2つの呼び出し方は、結果としては同じになります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; add 1 2
3
ghci&gt; (add 1) 2
3
</pre></div>


<p class="wp-block-paragraph"><code>add</code>の型シグネチャは、「<code>Int -&gt; Int -&gt; Int</code>」ですが、これは「<code>Int -&gt; (Int -&gt; Int)</code>」と書くことができます。後者の記載では「<code>Int</code>」を1つ引数にとって、「<code>(Int -&gt; Int)</code>」つまりは <code>Int</code>を受け取って<code>Int</code>を返す関数を返却すると読むことができます。</p>



<p class="wp-block-paragraph">つまり、「add 1 2」というのは、実際には2つのステップを踏みます。</p>



<ol class="wp-block-list">
<li><code>add 1</code>が評価されて<code>1</code>を加算するような関数が返却されます。この関数は引数を1つ受け取る関数です。</li>



<li>ステップ1で返却された関数の引数に<code>2</code>を適用して、結果の<code>3</code>を返却する。</li>
</ol>



<p class="wp-block-paragraph">これは引数が3つ、4つ、…と増えていっても同じです。1つ引数が適用されて関数が返却され、次の引数が適用されてまた関数が返却されるというのが繰り返されます。このような関数をカリー化された関数といいます。</p>



<p class="wp-block-paragraph">「Haskellのすべての関数は、引数を1つだけ取る」の意味はご理解いただけたでしょうか。では、これは何がうれしいのでしょうか。それが以降で説明する部分適用になります。</p>



<h3 class="wp-block-heading">部分適用 (Partial Application)</h3>



<p class="wp-block-paragraph"><span class="marker"><strong>部分適用 (Partial Application)</strong></span>は、関数にその関数がとる引数の一部だけを提供し、残りの引数を受け取るような新しい関数を生成することを言います。</p>



<p class="wp-block-paragraph">先ほども見てきた<code>add</code>関数を使って、部分適用の例を見てみましょう。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
add :: Int -&gt; Int -&gt; Int
add x y = x + y

-- 2を足し算する関数
add2 = add 2

-- 3を足し算する関数
add3 = add 3
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果例】
ghci&gt; add2 3
5
ghci&gt; add3 3
6
</pre></div>


<p class="wp-block-paragraph">上記の例では、<code>add</code>関数の引数<code>x</code>のみ値を渡して新しい関数を作成しています。先ほどカリー化でも見てきたように1つの引数だけ与えた場合には、返却値は関数となっているので、その関数に新しく名前(<code>add2</code>や<code>add3</code>)を付けて使うことができます。</p>



<p class="wp-block-paragraph">部分適用の利点は、既存の関数の再利用性とモジュール性を高めることができる点にあります。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box5"><div class="kaisetsu-box5-title">Note</div>
<p class="wp-block-paragraph">関数の引数は最も汎用的なものから順に並べるというのがベストプラクティスです。これは部分適用によりモジュールの再利用性を高めやすくなるためです。</p>



<p class="wp-block-paragraph">例えば、HTTP通信のリクエスト組み立てるような関数を考えた時にホスト名は最も汎用的といえます。このような引数を左側に持ってきておくと、ホスト名を指定した関数を作っておいて、後続のパラメータのみ変動させて使うようなこともできるようになります。</p>
</div>



<h3 class="wp-block-heading">カリー化と部分適用の違い</h3>



<p class="wp-block-paragraph">上記で「カリー化」と「部分適用」について説明してきましたが、これらはよく混同されがちです。しかし、これらは明確に異なる概念です。</p>



<p class="wp-block-paragraph">カリー化は、複数の引数をとる関数を<span class="marker2">引数を1つだけ取る関数の連鎖に変換するプロセス</span>のこと自体を指します。一方で、部分適用は、複数の引数をとる関数の<span class="marker2">一部に引数を渡して新しい関数を生成すること</span>です。</p>



<p class="wp-block-paragraph">これらは、明確に異なった概念ですので区別して理解してください。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellにおいて高階関数を理解するために重要となる「<span class="marker"><strong>カリー化(Currying)</strong></span>」と「<span class="marker"><strong>部分適用 (Partial Application)</strong></span>」について解説しました。</p>



<p class="wp-block-paragraph">カリー化は、複数の引数をとる関数を、引数を1つだけ取る関数の連鎖に変換するプロセスのことです。部分適用は、複数の引数をとる関数の一部に引数を渡して新しい関数を生成することでカリー化と関連しています。</p>



<p class="wp-block-paragraph">この記事では、カリー化と部分適用について、簡単な例を使いながら紹介しました。これらの概念は、理解していなくてもプログラムすることはできるのですが、純粋関数型プログラミング言語であるHaskellの理解を深めるのに非常に重要なので、ぜひ理解していただきたいと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-currying-partial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】foldl関数、foldr関数の基本的な使い方 ~畳み込み~</title>
		<link>https://haskell-tech.nkhn37.net/haskell-foldl-foldr-basic/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-foldl-foldr-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 30 Mar 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[foldl]]></category>
		<category><![CDATA[foldr]]></category>
		<category><![CDATA[高階関数]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=481</guid>

					<description><![CDATA[Haskellで畳み込み計算をするためのfoldl関数とfoldr関数の使い方を解説します。 畳み込み関数 (foldl, foldr) 畳み込みとは、適用する関数、初期値、畳み込み可能な型のデータ(例えばリスト)を受け]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellで畳み込み計算をするための<span class="marker"><strong><code>foldl</code>関数と<code>foldr</code>関数の使い方</strong></span>を解説します。</p>



<h2 class="wp-block-heading">畳み込み関数 (foldl, foldr)</h2>



<p class="wp-block-paragraph">畳み込みとは、適用する関数、初期値、畳み込み可能な型のデータ(例えばリスト)を受け取って単一の値にする計算のことを言います。Haskellでは、畳み込み関数の代表的なものとして<span class="marker"><strong><code>foldl</code></strong></span>関数と<span class="marker"><strong><code>foldr</code></strong></span>関数があります。</p>



<p class="wp-block-paragraph">これらの関数において、<code>l</code>は「left」、<code>r</code>は「right」を表しており、<code>foldl</code>は左畳み込み、<code>foldr</code>は右畳み込みと言います。これらは左から値を畳み込んでいくのか、右から値を畳み込んでいくのかの違いがあります。</p>



<p class="wp-block-paragraph"><code>foldl</code>関数や<code>foldr</code>関数のように引数に関数を受け取る関数は、高階関数と言います。高階関数の概要については「<a href="https://haskell-tech.nkhn37.net/haskell-higher-order-functions-basic/" target="_blank" rel="noreferrer noopener">高階関数の基本</a>」でまとめているので参考にしてください。畳み込み関数(<code>foldl</code>, <code>foldr</code>)は、高階関数の中でも代表的な関数であり、関数型プログラミングにおいて中心的な関数の一つです。他のプログラミング言語では、<code>reduce</code>という関数名の場合もあります。</p>



<p class="wp-block-paragraph">この記事では、畳み込み計算をするための<span class="marker"><strong><code>foldl</code>関数と<code>foldr</code>関数の使い方</strong></span>を解説します。</p>



<div class="wp-block-jin-gb-block-box concept-box5">
<p class="wp-block-paragraph">関数型プログラミングの中心的な関数としては他にも<code>map</code>関数や<code>filter</code>関数があります。以下のページでまとめていますので参考にしてください。</p>



<ul class="wp-block-list">
<li><a href="https://haskell-tech.nkhn37.net/haskell-map-function-basic/" target="_blank" rel="noreferrer noopener">map関数の基本的な使い方</a></li>



<li><a href="https://haskell-tech.nkhn37.net/haskell-filter-function-basic/" target="_blank" rel="noreferrer noopener">filter関数の基本的な使い方</a></li>
</ul>
</div>



<h2 class="wp-block-heading">foldl関数の基本的な使い方</h2>



<p class="wp-block-paragraph"><span class="marker"><strong><code>foldl</code></strong></span>関数は、Haskellにおいてリスト等の<code>Foldable</code>な型を畳み込むために使用します。「<code>l</code>」は「left」を表しており、<span class="marker"><strong>左畳み込み</strong></span>とも言われます。</p>



<p class="wp-block-paragraph"><code>foldl</code>関数の型シグネチャは以下のようになっています。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box4"><div class="kaisetsu-box4-title">foldl関数</div><div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
foldl :: Foldable t =&gt; (b -&gt; a -&gt; b) -&gt; b -&gt; t a -&gt; b
</pre></div></div>



<p class="wp-block-paragraph"><code>foldl</code>関数は、以下の3つの引数を取ります。</p>



<ol class="wp-block-list">
<li>関数 <code>(b -&gt; a -&gt; b)</code>：リストの各要素と累積値に適用され、新しい累積値を生成します。例えば、<code>(+)</code>は2つの数を受け取り、その和を返す2項関数です。</li>



<li>初期値 <code>b</code>：畳み込みを開始するための値です。例えば、数値リストを畳み込む場合の初期値として<code>0</code>がよく使用されます。</li>



<li>畳み込まれるリスト <code>t a</code>：Foldable型クラスのインスタンスであり、畳み込み対象となるデータです。例えば、<code>Int</code>のリスト(<code>[Int]</code>)等が該当します。</li>
</ol>



<p class="wp-block-paragraph">ここで、<code>Foldable</code>というのは型クラスを表しています。<code>t</code>は<code>Foldable</code>型クラスのインスタンスである必要があります。今回は簡単のため<code>Foldable</code>のインスタンスであるリストを使った例を紹介しますが、他の型でも<code>foldl</code>関数は使用できます。他の<code>Foldable</code>型クラスのインスタンスである型としては<code>Tree</code>型や<code>Maybe</code>型などが該当します。</p>



<h3 class="wp-block-heading">foldl関数の使用例</h3>



<h4 class="wp-block-heading">数値の畳み込み</h4>



<p class="wp-block-paragraph"><code>foldl</code>関数を使用して、数値のリストを畳み込む場合には以下のようにします。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 数値の畳み込み
plusFoldl :: &#x5B;Int] -&gt; Int
plusFoldl xs = foldl (+) 0 xs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果例】
ghci&gt; plusFoldl &#x5B;1, 2, 3, 4, 5]
15
</pre></div>


<p class="wp-block-paragraph">上記で定義した<code>plusFoldl</code>関数は、<code>foldl</code>を使用してリスト<code>xs</code>の中の全ての数値を<span class="marker2">左から</span>順に加算<code>(+)</code>し、その合計値を返します。左から順に足しこんでいく基準の初期値は<code>0</code>となります。実行結果例をわかる通り<code>[1, 2, 3, 4, 5]</code>を引数に渡すと結果は<code>15</code>となります。</p>



<h3 class="wp-block-heading">foldl関数の動作を理解する</h3>



<p class="wp-block-paragraph">上記の例を見て<code>foldl</code>関数がどのような結果となるかは分かったかと思いますが、より関数の動作を理解するには自分で実装するとどうなるかを考えてみることが非常に役に立ちます。</p>



<p class="wp-block-paragraph"><code>foldl</code>関数は、型シグネチャを見るとわかる通りリスト限定のものではありませんが、リストを前提として左畳み込みを自分で実装してみる場合の<code>myFoldl</code>関数は以下のように実装することができます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- foldlを自分で実装する
myFoldl :: (b -&gt; a -&gt; b) -&gt; b -&gt; &#x5B;a] -&gt; b
myFoldl f z &#x5B;] = z
myFoldl f z (x:xs) = myFoldl f (f z x) xs
</pre></div>


<p class="wp-block-paragraph">上記の関数において<code>f</code>を<code>(+)</code>、<code>z</code>を<code>0</code>、xsを<code>[1, 2, 3, 4, 5]</code>と考えてどのような動きをしているか考えてみましょう。具体的にどのように処理が流れていくかを記載してみると以下のようになります。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="682" src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-5-1024x682.png" alt="foldl関数の説明" class="wp-image-500" srcset="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-5-1024x682.png 1024w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-5-300x200.png 300w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-5-768x511.png 768w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-5.png 1326w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-5-1024x682.png 856w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph"><code>myFoldl</code>関数は、再帰的に定義されています。「<code>myFoldl f z (x:xs) = myFoldl f (f z x) xs</code>」の部分に注目してみると、初期値<code>0</code>とリストの先頭要素<code>1</code>に対して引数で与えられた関数<code>(+)</code>を適用し、その結果が次の初期値となっています。このように順に計算をしていくと計算結果の<code>15</code>が得られます。具体的には<code>(((((0 + 1) + 2) + 3) + 4) + 5) = 15</code>のように計算されていることが分かるかと思います。</p>



<h2 class="wp-block-heading">foldr関数の基本的な使い方</h2>



<p class="wp-block-paragraph"><span class="marker"><strong><code>foldr</code></strong></span>関数も、<code>foldl</code>関数と同様にリスト等の<code>Foldable</code>な型を畳み込むために使用します。「<code>r</code>」は「right」を表しており、<span class="marker"><strong>右畳み込み</strong></span>とも言われます。</p>



<p class="wp-block-paragraph"><code>foldr</code>関数の型シグネチャは以下のようになっています。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box4"><div class="kaisetsu-box4-title">foldr関数</div><div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
foldr :: Foldable t =&gt; (a -&gt; b -&gt; b) -&gt; b -&gt; t a -&gt; b
</pre></div></div>



<p class="wp-block-paragraph"><code>foldl</code>関数と非常に似た型シグネチャであることが分かるかと思いますが、違いとしては第1引数で受け取る関数の型が<code>(a -> b -> b)</code>となっていて、<code>a</code>と<code>b</code>が逆転しています。これは、<code>foldr</code>関数がリストの要素を右から畳み込んでいくことを意味しています。</p>



<h3 class="wp-block-heading">foldr関数の使用例</h3>



<h4 class="wp-block-heading">数値の畳み込み</h4>



<p class="wp-block-paragraph"><code>foldl</code>関数と同じように<code>foldr</code>関数を用いて数値の畳み込みをする例を見てみましょう。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 数値の畳み込み
plusFoldr :: &#x5B;Int] -&gt; Int
plusFoldr xs = foldr (+) 0 xs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果例】
ghci&gt; plusFoldr &#x5B;1, 2, 3, 4, 5]
15
</pre></div>


<p class="wp-block-paragraph">上記で定義した<code>plusFoldr</code>関数は、<code>foldr</code>を使用してリスト<code>xs</code>の中の全ての数値を<span class="marker2">右から</span>順に加算<code>(+)</code>し、その合計値を返します。右から順に足しこんでいく基準となる初期値は<code>0</code>となります。実行結果例をわかる通り、<code>[1, 2, 3, 4, 5]</code>を引数に渡すと結果は15となります。</p>



<h3 class="wp-block-heading">foldr関数の動作を理解する</h3>



<p class="wp-block-paragraph">数値を畳み込む例を見てきましたが結果としては<code>foldl</code>関数と<code>foldr</code>関数では同じ結果になりました。しかし、内部的には全く異なる動作をしています。</p>



<p class="wp-block-paragraph"><code>foldl</code>関数でも見てきたように<code>foldr</code>関数についても、自分で実装してみることにしてみましょう。<code>foldr</code>関数をリストに対して実装した<code>myFoldr</code>関数は以下のようになります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- foldrを自分で実装する
myFoldr :: (a -&gt; b -&gt; b) -&gt; b -&gt; &#x5B;a] -&gt; b
myFoldr _ z &#x5B;] = z
myFoldr f z (x:xs) = f x (myFoldr f z xs)
</pre></div>


<p class="wp-block-paragraph">上記の関数において<code>f</code>を<code>(+)</code>、<code>z</code>を<code>0</code>、xsを<code>[1, 2, 3, 4, 5]</code>と考えてどのような動きをしているか考えてみましょう。具体的にどのように処理が流れていくかを記載してみると以下のようになります。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" width="1024" height="546" src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-6-1024x546.png" alt="foldr関数の説明" class="wp-image-503" style="width:700px;height:auto" srcset="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-6-1024x546.png 1024w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-6-300x160.png 300w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-6-768x410.png 768w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-6.png 1455w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-6-1024x546.png 856w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph"><code>myFoldr</code>関数についても再帰的に定義されています。「<code>myFoldr f z (x:xs) = f x (myFoldr f z xs)</code>」の部分について着目してみると、リストの先頭要素が前に来て、初期値が後ろにスライドし、残りのリストを使って再度<code>myFoldr</code>が適用されていることが分かるかと思います。</p>



<p class="wp-block-paragraph">このように書き下していくと最終的には「<code>myfoldr (+) 0 []</code>」という形となり、これは「<code>myFoldr _ z [] = z</code>」の定義より初期値<code>z</code>、今回の例では<code>0</code>になります。最終的には、<code>(1 + (2 + (3 + (4 + (5+0)))))</code>のように右から(+)で畳み込まれている計算となっていることが分かるかと思います。</p>



<p class="wp-block-paragraph">上記で見てきた通り<code>foldl</code>関数と<code>foldr</code>関数は、左から畳み込むのか、右から畳み込むのかという点で具体的な動作が異なっています。</p>



<h2 class="wp-block-heading">foldl関数とfoldr関数の違い</h2>



<h3 class="wp-block-heading">適用する関数による結果の違い</h3>



<p class="wp-block-paragraph">上記までで<code>foldl</code>関数と<code>foldr</code>関数を見てきました。足し算<code>(+)</code>を例に見る限りでは、結果は同じでした。しかし、各関数の動作を理解するために動作をステップごとに書いてみましたが「左から畳み込むのか」「右から畳み込むのか」という違いがありました。</p>



<p class="wp-block-paragraph">例えば、適用する関数として引き算<code>(-)</code>を指定した場合には、以下のように結果が大きく変わります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- foldlの場合
minusFoldl :: &#x5B;Int] -&gt; Int
minusFoldl xs = foldl (-) 0 xs

-- foldrの場合
minusFoldr :: &#x5B;Int] -&gt; Int
minusFoldr xs = foldr (-) 0 xs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果例】
ghci&gt; minusFoldl &#x5B;1, 2, 3, 4, 5]
-15
ghci&gt; minusFoldr &#x5B;1, 2, 3, 4, 5]
3
</pre></div>


<p class="wp-block-paragraph">上記の例についても具体的に書き下してみると以下のような計算になっていることが分かります。</p>



<ul class="wp-block-list">
<li><code>minusFoldl</code>の場合：<code>(((((0 - 1) - 2) - 3) - 4) - 5) = -15</code> </li>



<li><code>minusFoldr</code>の場合：<code>(1 - (2 - (3 - (4 - (5 - 0))))) = 3</code></li>
</ul>



<p class="wp-block-paragraph">上記のように畳み込む方向が左からから、右からかという違いがあるため、適用する関数によって大きな違いが出ることに注意が必要です。</p>



<h3 class="wp-block-heading">無限リストに対する挙動の違い</h3>



<p class="wp-block-paragraph">Haskellは遅延評価言語であるため、<code>foldr</code>は無限リストに対しても使用することが可能な場合があります。これは、結果を得るためにリスト全体を評価する必要がないケースで利点となります。</p>



<p class="wp-block-paragraph">一方で、<code>foldl</code>は基本的にリストの全体を評価しようとするため、無限リストには適していません。無限リストに対して<code>foldl</code>を適用すると無限ループとなってしまいます。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellで畳み込み計算をするための<span class="marker"><strong><code>foldl</code>関数と<code>foldr</code>関数の使い方</strong></span>を解説しました。</p>



<p class="wp-block-paragraph">畳み込みとは、適用する関数、初期値、畳み込み可能な型のデータ(例えばリスト)を受け取って単一の値にする計算のことを言います。<code>foldl</code>関数は左畳み込み、<code>foldr</code>関数は右畳み込みといい、値を畳み込む順序が異なっています。</p>



<p class="wp-block-paragraph">この記事では、<code>foldl</code>関数と<code>foldr</code>関数の各関数の概要と基本的な使い方、そして違いについて説明しました。</p>



<p class="wp-block-paragraph">畳み込み関数(<code>foldl</code>, <code>foldr</code>)は、<code>map</code>関数や<code>filter</code>関数と同様に関数型プログラミングのHaskellにとっては代表的で重要な関数です。しっかりと動作を理解して使いこなせるようにしていただきたいと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-foldl-foldr-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】filter関数の基本的な使い方</title>
		<link>https://haskell-tech.nkhn37.net/haskell-filter-function-basic/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-filter-function-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sun, 03 Mar 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[高階関数]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=473</guid>

					<description><![CDATA[Haskellでfilter関数を使用してリストから特定の条件を満たす要素のみ抽出する方法を解説します。 filter関数によるデータ抽出 filter関数は、関数とリストを受け取って、リストから特定の条件を満たす要素の]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellで<span class="marker"><strong>filter関数を使用してリストから特定の条件を満たす要素のみ抽出する方法</strong></span>を解説します。</p>



<h2 class="wp-block-heading">filter関数によるデータ抽出</h2>



<p class="wp-block-paragraph"><span class="marker"><strong><code>filter</code>関数</strong></span>は、関数とリストを受け取って、リストから特定の条件を満たす要素のみ抽出する関数です。</p>



<p class="wp-block-paragraph">このように引数に関数を受け取る関数は、高階関数と言います。高階関数の概要については「<a href="https://haskell-tech.nkhn37.net/haskell-higher-order-functions-basic/" target="_blank" rel="noreferrer noopener">高階関数の基本</a>」でまとめているので参考にしてください。filter関数は高階関数の中でも代表的な関数であり、関数型プログラミングにおいて中心的な関数の一つです。</p>



<p class="wp-block-paragraph">本記事では、<span class="marker"><strong><code>filter</code>関数を使用してリストから特定の条件を満たす要素のみ抽出する方法</strong></span>を紹介します。</p>



<h3 class="wp-block-heading">filter関数の基本的な使い方</h3>



<p class="wp-block-paragraph">filter関数の型シグネチャとしては、以下のようになっています。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box4"><div class="kaisetsu-box4-title">filter関数</div><div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
filter :: (a -&gt; Bool) -&gt; &#x5B;a] -&gt; &#x5B;a]
</pre></div></div>



<p class="wp-block-paragraph">上記の型シグネチャの意味は「<code>(a -> Bool)</code>：<code>a</code>型を引数として受け取り、Boolを返却する関数」と「<code>[a]</code>：<code>a</code>型のリスト」の2つの引数を受け取って、「<code>[a]</code>：<code>a</code>型のリスト」を返却する関数ということを意味しています。</p>



<p class="wp-block-paragraph">簡単に言うと、<code>filter</code>関数は第1引数で受け取った判定の関数を使用し、第2引数のリストから関数の判定で<code>True</code>になる要素のみ抽出したリストを返却します。第1引数で指定する関数は、<code>Bool</code>を返却するような関数である必要があります。</p>



<p class="wp-block-paragraph">具体的な使用例を見ていただくとイメージがつかめると思いますので、以降でいくつかの使用例を使いながらfilter関数の使い方を説明します。</p>



<div class="wp-block-jin-gb-block-box concept-box5">
<p class="wp-block-paragraph">型シグネチャの基本については「<a href="https://haskell-tech.nkhn37.net/haskell-type-signatures-variables/" target="_blank" rel="noreferrer noopener">型シグネチャと型変数の基本</a>」でまとめているので参考にしてください。</p>
</div>



<h3 class="wp-block-heading">filter関数の使用例</h3>



<p class="wp-block-paragraph">ここではfilter関数の簡単な使用例を使ってイメージをつかんでもらいたいと思います。以下は説明のための簡単な例です。引数に渡す関数を変更することで様々な抽出ができますので、色々と試してみてください。</p>



<h4 class="wp-block-heading">特定の数値条件を満たす要素の抽出</h4>



<p class="wp-block-paragraph">特定の数値条件を満たすような抽出の例を見てみましょう。<code>5</code>よりも大きい数値のみ抽出する場合には、<code>filter</code>関数を使用して以下のようにします。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 5よりも大きい数値のみ抽出する
valuesOver5 :: &#x5B;Int]
valuesOver5 = filter (&gt; 5) &#x5B;1, 4, 7, 2, 8, 9, 3, 10, 5, 6]
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果】
ghci&gt; valuesOver5 
&#x5B;7,8,9,10,6]
</pre></div>


<p class="wp-block-paragraph">上記では、<code>5</code>より大きいことを判定する関数<code>(> 5)</code>を、受け取ったリストに対して適用して条件に一致(<code>True</code>)する要素を含むリストを返却します。結果としては、5より大きい値のみ含むリストになっていることが分かります。</p>



<h4 class="wp-block-heading">偶数のみ抽出する</h4>



<p class="wp-block-paragraph">リストから偶数のみ抽出する例を見てみましょう。偶数を抽出する際には、<code>even</code>関数を使用します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 偶数のみ抽出する
valuesEven :: &#x5B;Int]
valuesEven = filter even &#x5B;1, 4, 7, 2, 8, 9, 3, 10, 5, 6]
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果】
ghci&gt; valuesEven 
&#x5B;4,2,8,10,6]
</pre></div>


<p class="wp-block-paragraph">上記のように、Haskellに標準で用意されている<code>even</code>関数を使っても要素の抽出をすることが可能です。結果を見ると偶数のみ抽出されたリストになっていることが分かります。</p>



<h4 class="wp-block-heading">文字列のリストから特定の文字を含む要素だけを抽出する</h4>



<p class="wp-block-paragraph">上記では数値の例を見てきましたが、もちろん文字列のリストに対してもフィルタが可能です。例えば、リスト内の文字列から特定の文字を含むものだけを抽出する例を考えます。リスト内に文字を含むかどうかは、<code>elem</code>関数を使用して以下のように指定します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 文字列のリストから特定の文字を含む要素だけを抽出する
strsElemA :: &#x5B;String]
strsElemA = filter (elem &#039;a&#039;) &#x5B;&quot;apple&quot;, &quot;banana&quot;, &quot;cherry&quot;, &quot;pine&quot;, &quot;orange&quot;]
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果】
ghci&gt; strsElemA 
&#x5B;&quot;apple&quot;,&quot;banana&quot;,&quot;orange&quot;]
</pre></div>


<p class="wp-block-paragraph">上記結果では、文字列(<code>String</code>)を含むリストから指定した要素<code>'a'</code>を含むような要素のみを抽出しています。</p>



<p class="wp-block-paragraph">上記で見てきたように<code>filter</code>関数を使用すると、様々なリストから特定の条件に一致した要素を抽出することが可能になります。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellで<span class="marker"><strong>filter関数を使用してリストから特定の条件を満たす要素のみ抽出する方法</strong></span>を解説しました。</p>



<p class="wp-block-paragraph"><code>filter</code>関数は、関数とリストを受け取って、リストから特定の条件を満たす要素のみ抽出する関数で、関数型プログラミングにおいて中心的な高階関数の一つです。簡単な例を用いて<code>filter</code>関数の使用方法を紹介しています。</p>



<p class="wp-block-paragraph">filter関数は非常に基本的で中心的な高階関数なので、ぜひ使い方をしっかりと覚えてもらいたいと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-filter-function-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】map関数の基本的な使い方</title>
		<link>https://haskell-tech.nkhn37.net/haskell-map-function-basic/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-map-function-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 02 Mar 2024 21:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[高階関数]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=413</guid>

					<description><![CDATA[Haskellでmap関数を使用してリストの各要素に関数を適用する方法を解説します。 map関数による関数適用 map関数は、関数とリストを受け取って、リストの各要素に関数を適用した結果を返す関数です。 このように引数に]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellで<span class="marker"><strong>map関数を使用してリストの各要素に関数を適用する方法</strong></span>を解説します。</p>



<h2 class="wp-block-heading">map関数による関数適用</h2>



<p class="wp-block-paragraph"><span class="marker"><strong><code>map</code>関数</strong></span>は、関数とリストを受け取って、リストの各要素に関数を適用した結果を返す関数です。</p>



<p class="wp-block-paragraph">このように引数に関数を受け取る関数は、高階関数と言います。高階関数の概要については「<a href="https://haskell-tech.nkhn37.net/haskell-higher-order-functions-basic/" target="_blank" rel="noreferrer noopener">高階関数の基本</a>」でまとめているので参考にしてください。<code>map</code>関数は高階関数の中でも代表的な関数であり、関数型プログラミングにおいて中心的な関数の一つです。</p>



<p class="wp-block-paragraph">本記事では、<span class="marker"><strong><code>map</code>関数を使用してリストの各要素に関数を適用する方法</strong></span>を紹介します。</p>



<h3 class="wp-block-heading">map関数の基本的な使い方</h3>



<p class="wp-block-paragraph"><code>map</code>関数の型シグネチャとしては、以下のようになっています。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box4"><div class="kaisetsu-box4-title">map関数</div><div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
map :: (a -&gt; b) -&gt; &#x5B;a] -&gt; &#x5B;b]
</pre></div></div>



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



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



<div class="wp-block-jin-gb-block-box concept-box5">
<p class="wp-block-paragraph">型シグネチャの基本については「<a href="https://haskell-tech.nkhn37.net/haskell-type-signatures-variables/" target="_blank" rel="noreferrer noopener">型シグネチャと型変数の基本</a>」でまとめているので参考にしてください。</p>
</div>



<h3 class="wp-block-heading">map関数の使用例</h3>



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



<h4 class="wp-block-heading">すべての要素を2倍にする</h4>



<p class="wp-block-paragraph">リストのすべての要素を2倍にする場合には、map関数を使用して以下のようにします。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 全ての要素を2倍にする
doubles :: &#x5B;Int] -&gt; &#x5B;Int]
doubles xs = map (*2) xs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果】
ghci&gt; doubles &#x5B;1,2,3,4,5]
&#x5B;2,4,6,8,10]
</pre></div>


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



<h4 class="wp-block-heading">文字列のリストを大文字にする</h4>



<p class="wp-block-paragraph">リストの文字列を大文字にする場合には、<code>map</code>関数を使用して以下のようにします。ここでは文字(<code>Char</code>)を大文字にするために、<code>Data.Char</code>の<code>toUpper</code>関数をインポートして使用します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
import Data.Char (toUpper)

-- 文字列のリストを大文字にする
toUpperCase :: &#x5B;String] -&gt; &#x5B;String]
toUpperCase strs = map (map toUpper) strs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果】
ghci&gt; toUpperCase &#x5B;&quot;hello&quot;,&quot;world&quot;]
&#x5B;&quot;HELLO&quot;,&quot;WORLD&quot;]
</pre></div>


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



<h4 class="wp-block-heading">リスト内の数値を文字列に変換する</h4>



<p class="wp-block-paragraph">リスト内の数値を文字列に変換する場合には、map関数を使用して以下のようにします。文字列にする場合には、<code>show</code>関数を使用します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- リスト内の数値を文字列に変換する
toStrings :: &#x5B;Int] -&gt; &#x5B;String]
toStrings nums = map show nums
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行結果】
ghci&gt; toStrings &#x5B;1,2,3,4,5]  
&#x5B;&quot;1&quot;,&quot;2&quot;,&quot;3&quot;,&quot;4&quot;,&quot;5&quot;]
</pre></div>


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



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellで<span class="marker"><strong>map関数を使用してリストの各要素に関数を適用する方法</strong></span>を解説しました。</p>



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



<p class="wp-block-paragraph"><code>map</code>関数は非常に基本的で中心的な高階関数なのでぜひ使い方をしっかりと覚えてもらいたいと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-map-function-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】型シグネチャと型変数の基本</title>
		<link>https://haskell-tech.nkhn37.net/haskell-type-signatures-variables/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-type-signatures-variables/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 02 Mar 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[型]]></category>
		<category><![CDATA[型シグネチャ]]></category>
		<category><![CDATA[型変数]]></category>
		<category><![CDATA[型推論]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=438</guid>

					<description><![CDATA[Haskellの強力な型システムにおいて重要な役割を果たす「型シグネチャ」と「型変数」について基本を解説します。 型シグネチャと型変数 Haskellは、純粋関数型プログラミング言語のひとつで、強力な型システムを持つ静的]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellの強力な型システムにおいて重要な役割を果たす「<span class="marker"><strong>型シグネチャ</strong></span>」と「<span class="marker"><strong>型変数</strong></span>」について基本を解説します。</p>



<h2 class="wp-block-heading">型シグネチャと型変数</h2>



<p class="wp-block-paragraph">Haskellは、純粋関数型プログラミング言語のひとつで、強力な型システムを持つ静的型付け言語です。Haskellの強力な型システムでは、プログラムの正確性と安全性を高めており、型についてしっかりと理解してプログラミングに取り組むことが非常に重要です。</p>



<p class="wp-block-paragraph">Haskellのプログラムにおいて「<span class="marker"><strong>型シグネチャ</strong></span>」と「<span class="marker"><strong>型変数</strong></span>」というものは非常に重要な役割を持っており、これらによりコンパイラはプログラム内の一貫性をチェックし、型に関するエラーを早期に発見します。</p>



<p class="wp-block-paragraph">本記事では、型シグネチャと型変数についての基本を解説します。</p>



<h3 class="wp-block-heading">変数の型シグネチャ</h3>



<p class="wp-block-paragraph">Haskellでは、変数に対して<span class="marker"><strong>型シグネチャ(type signatures)</strong></span>を付与することができます。型シグネチャとは変数や関数の型を宣言するためのものです。</p>



<p class="wp-block-paragraph">例えば、整数値を持つ変数を宣言する場合は、以下のように型シグネチャを使用します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
myNumber :: Int
myNumber = 42
</pre></div>


<p class="wp-block-paragraph">この例では、<code>myNumber</code>という変数は、<code>Int</code>型であることを宣言しています。型シグネチャの宣言では、「<code>::</code>」の後に型を記述します。これにより、<code>myNumber</code>は整数を意味するようになるため、それ以外の値を割り当てるとコンパイルエラーとなります。</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="617" height="234" src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-2.png" alt="型シグネチャ 変数" class="wp-image-444" style="width:374px;height:auto"/></figure>
</div>


<h3 class="wp-block-heading">関数の型シグネチャ</h3>



<h4 class="wp-block-heading">1引数の関数の型シグネチャ</h4>



<p class="wp-block-paragraph">関数に対しても同様に型シグネチャを定義することが可能です。関数の型シグネチャでは、引数の型と返却値の型を指定します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
double :: Int -&gt; Int
double x = x * 2
</pre></div>


<p class="wp-block-paragraph">上記例の<code>double</code>関数は、<code>Int</code>型の引数をとり、2をかけた<code>Int</code>型の返却値を返却します。関数の型シグネチャでは、引数の型と返却値の型を「<code>-></code>」でつなぎます。</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="794" height="328" src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-1.png" alt="型シグネチャ 関数 1引数" class="wp-image-442" style="width:500px"/></figure>
</div>


<h4 class="wp-block-heading">複数の引数を持つ関数の型シグネチャ</h4>



<p class="wp-block-paragraph">複数の引数を持つ関数の型シグネチャは、慣れるのに少し時間がかかるかもしれません。例で見てみましょう。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
add :: Int -&gt; Int -&gt; Int
add x y = x + y
</pre></div>


<p class="wp-block-paragraph">上記例の<code>add</code>関数は<code>x</code>と<code>y</code>の二つの引数を取ります。「<code>-></code>」で順番に型が列挙されているのですが、どれが引数の型でどれが戻り値の型かを明確に区別する方法がないのが少し厄介な点です。</p>



<p class="wp-block-paragraph">一番簡単な覚え方としては「最後の型が常に戻り値の型である」ということです。上記例では、1番目の<code>Int</code>は引数<code>x</code>の型、2番目の<code>Int</code>は引数<code>y</code>の型、そして最後の<code>Int</code>が返却値<code>x+y</code>の型ということになります。</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="905" height="414" src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-3.png" alt="型シグネチャ 関数 複数の引数" class="wp-image-446" style="width:551px;height:auto" srcset="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-3.png 905w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-3-300x137.png 300w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-3-768x351.png 768w, https://haskell-tech.nkhn37.net/wp-content/uploads/2024/03/image-3.png 856w" sizes="(max-width: 905px) 100vw, 905px" /></figure>
</div>


<h3 class="wp-block-heading">型変数</h3>



<p class="wp-block-paragraph">これまで型シグネチャについてみてきましたが、Haskellで定義されている一般的な型(<code>Int</code>)を用いた例で見てきました。ここで受け取った引数をそのまま返却するような<code>identity</code>関数を考えてみましょう。（Haskellには、同じ動作の<code>id</code>関数がありますが、ここではあえて自分で定義します）</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
identity x = x
</pre></div>


<p class="wp-block-paragraph">この<code>identity</code>関数の型シグネチャはどう書くと良いでしょうか。引数として与えることができる型は、<code>Int</code>、<code>Double</code>、<code>Char</code>など様々考えられます。それぞれの型のために「<code>identityInt</code>」「<code>identityDouble</code>」「<code>identityChar</code>」といった関数を個別に定義するのは、非常に大変にも関わらず無意味な作業です。</p>



<p class="wp-block-paragraph">このような問題を解決するために、Haskellでは<span class="marker"><strong>型変数(type variables)</strong></span>があります。型変数を使用すると<code>identity</code>関数の型シグネチャは以下のように記載できます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
identity :: a -&gt; a
identity x = x
</pre></div>


<p class="wp-block-paragraph">ここで「<code>a</code>」が型変数を表します。この<code>a</code>は、<code>Int</code>や<code>Double</code>、<code>Char</code>などに置き換えても問題ないことを意味しており、型変数を使うことで任意の型を表すことができます。型変数は、一般的にアルファベットの小文字1文字で表現されます。例えば、<code>a</code>、<code>b</code>、<code>c</code>といったものがよく使用されます。これは型変数を簡潔にし、コードの可読性を高めるためです。</p>



<p class="wp-block-paragraph">なお、Haskellの文法上は型変数に<code>myVar</code>のような小文字から始まる文字列を使用することも可能ですが、任意の型を示す変数に名前を付けることに意味はあまりなくコードの可読性が悪くなる可能性があるため、アルファベット1文字を使うのが良いでしょう。</p>



<p class="wp-block-paragraph">また、型変数は複数使用することも可能です。例えば「<code>func :: a -> b -> a</code>」というような型シグネチャの関数があった場合には、1番目の引数と2番目の引数は異なる型でよいですが、返却値は1番目の引数と同じ型である必要があります。なお、1番目の引数と2番目の引数が同じ型であることは問題ありません。この型シグネチャで求めているのは、1番目の引数と返却値の型が同じであるということです。</p>



<p class="wp-block-paragraph">上記のように型変数を用いることで、任意の型を表現することができます。ただし、任意の型を許容するため関数内の処理が問題なく動作するかは慎重にプログラミングする必要があります。明確に型を絞って提供したい関数は、型を明示した型シグネチャとして実装するべきでしょう。</p>



<h2 class="wp-block-heading">型推論</h2>



<p class="wp-block-paragraph">上記で、変数や関数の型の情報を明示する型シグネチャや型変数の記述方法を説明しました。ただし、Haskellは強力な<span class="marker"><strong>型推論(type inference)</strong></span>の機能を持っています。型推論とは、プログラムの文脈からコンパイラが自動的に変数や関数の型を推論する機能です。</p>



<p class="wp-block-paragraph">このため、型シグネチャを記載することは実は必須ではありません。しかし、型シグネチャを明示的に記述することには利点があります。特に、複雑な関数や型推論による曖昧さを排除したい場合には、意図した型が使用されることを保証するために、明確に型シグネチャを使用する方が適切です。</p>



<p class="wp-block-paragraph">また、型シグネチャはそれを見るだけで変数や関数の意図をある程度解釈できるため、プログラムのドキュメントとしても機能します。これによりコードの可読性を高める効果があります。</p>



<p class="wp-block-paragraph">関数型プログラミングであるHaskellでは、型を基準にプログラミングを行います。そのため、実装する前に必然的に関数の型について考えることになります。型シグネチャを書くことは、Haskellの開発においてとても自然なことです。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellの強力な型システムにおいて重要な役割を果たす「<span class="marker"><strong>型シグネチャ</strong></span>」と「<span class="marker"><strong>型変数</strong></span>」について基本を解説しました。</p>



<p class="wp-block-paragraph">Haskellの型シグネチャと型変数は、プログラムの型の安全性と柔軟性を高めるための強力なツールとなっています。型シグネチャにより関数や変数の期待する型を明示的に宣言することでコンパイラは型のミスマッチを効率的に検出できます。</p>



<p class="wp-block-paragraph">また、型推論についても簡単に触れ、型シグネチャは必須ではないことを説明しました。しかし、型シグネチャはプログラムの品質を高めるために効果があるため、基本的に書くように意識することを推奨します。</p>



<p class="wp-block-paragraph">型シグネチャや型変数が読めるようになるとHaskellのプログラムがとても理解しやすくなってきます。ぜひ、型シグネチャの基本的なところを理解してほしいと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-type-signatures-variables/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】高階関数の基本</title>
		<link>https://haskell-tech.nkhn37.net/haskell-higher-order-functions-basic/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-higher-order-functions-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Thu, 22 Feb 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[高階関数]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=416</guid>

					<description><![CDATA[関数型プログラミング言語における中心的な概念である高階関数の基本について解説します。 高階関数の基本概念 高階関数（Higher-order functions）は、関数型プログラミング言語における中心的な概念で、プログ]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">関数型プログラミング言語における中心的な概念である<span class="marker"><strong>高階関数</strong></span>の基本について解説します。</p>



<h2 class="wp-block-heading">高階関数の基本概念</h2>



<p class="wp-block-paragraph"><span class="marker"><strong>高階関数（Higher-order functions）</strong></span>は、関数型プログラミング言語における中心的な概念で、プログラミングにおける表現力を大きく高めることができます。</p>



<p class="wp-block-paragraph">高階関数は、他の関数を引数として受け取るか、または結果として関数を返すことができます。この特徴により、コードの再利用性が向上し、より柔軟なプログラミングが可能になります。</p>



<p class="wp-block-paragraph">本記事では、高階関数の特徴やHaskellにおける実装例を紹介します。</p>



<h3 class="wp-block-heading">高階関数の特徴</h3>



<p class="wp-block-paragraph">高階関数は、以下のような特徴を持つ関数です。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>特徴</th><th>説明</th></tr></thead><tbody><tr><td>第１級オブジェクトとしての関数</td><td>Haskellを含む多くの関数型プログラミング言語では、関数を第１級オブジェクトとして扱います。<br>第１級オブジェクトは、変数に割り当てたり、データ構造に格納したり、他の関数に引数として渡したり、関数からの戻り値として返すことが可能です。</td></tr><tr><td>抽象化と再利用性の向上</td><td>高階関数を使用すると、特定の操作を抽象化し、異なる文脈(コンテキスト)での再利用性が高まります。</td></tr><tr><td>コードの簡潔化</td><td>高階関数を使用により、コードをより簡潔にし、意図を明確にすることができます。複雑なループや条件分岐を抽象化して、コードの読みやすさと保守性を向上できます。</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">高階関数は、上記のような非常に有用な特性を持っているため、Haskellのような関数型プログラミング言語に限らず様々な言語でも取り込まれていっています。例えば、Pythonはマルチパラダイム言語であり、高階関数を使用することが可能です。Pythonのデコレータは、高階関数を用いた仕組みを簡単に利用できるようにする仕組みとして機能しています。</p>



<p class="wp-block-paragraph">ただし、高階関数は良い側面ばかりとも言えません。高階関数を過度に使用することでコードの読みにくさを引き起こす可能性があったり、デバッグがしにくくなる可能性もある点は理解しておいてください。</p>



<h3 class="wp-block-heading">高階関数のHaskell実装例</h3>



<p class="wp-block-paragraph">ここでは、Haskellでの実装例を使って高階関数のイメージをつかんでもらおうかと思います。高階関数を実装する際には、関数を受け取るか、または関数を返すようにします。例として、二つの関数を合成する高階関数<code>compose</code>をHaskellで実装してみます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 2つの関数を合成する関数
compose :: (b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; c
compose f g x = f (g x)
</pre></div>


<p class="wp-block-paragraph">上記関数は、関数<code>f</code>、関数<code>g</code>と入力<code>x</code>を受け取って、<code>x</code>に<code>g</code>を適用し、その結果に<code>f</code>を適用するという関数になっています。つまり、数学的に書いてみるとf(g(x))を返す関数です。</p>



<p class="wp-block-paragraph">では、この関数をうまく使って、5を加算する関数(<code>add5</code>)と2を乗算をする関数(<code>multiply2</code>)を順番に適用するような関数を作ることを考えてみましょう。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 5を加算する関数
add5 :: Int -&gt; Int
add5 x = x + 5

-- 2を乗算する関数
multiply2 :: Int -&gt; Int
multiply2 x = x * 2
</pre></div>


<p class="wp-block-paragraph">上記の二つの関数を順番に適用する関数は、<code>compose</code>を使って以下のように定義できます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- add5を適用してから、multiply2を適用する関数
add5AndMultiply2 :: Int -&gt; Int
add5AndMultiply2 = compose multiply2 add5
</pre></div>


<p class="wp-block-paragraph">ここで、<code>compose</code>関数は、関数自体を引数に渡すことができるため、引数の部分に「<code>add5</code>」や「<code>multiply2</code>」といった関数を指定することができます。この式は「<code>add5AndMultiply2 x = compose multiply2 add5 x</code>」とも書けますが、Haskellでは、η簡約（eta reduction）で<code>x</code>を省略することができます。</p>



<p class="wp-block-paragraph">上記の定義は、<code>compose</code>関数が「Int型の<code>x</code>を受け取ってIntの結果を返却するような関数」を返却し、その関数が<code>add5AndMultiply2</code>に割り当てられていることを意味します。</p>



<p class="wp-block-paragraph">具体的に使用例を見てもらえるとイメージがつかみやすいかもしれません。ghciというHaskellのインタプリタを使って<code>add5AndMultiply2</code>実行した結果は以下の通りです。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
ghci&gt; add5AndMultiply2 5
20
ghci&gt; add5AndMultiply2 10
30
</pre></div>


<p class="wp-block-paragraph">上記の結果から、<code>add5AndMultiply2</code>が、5を加算する関数(<code>add5</code>)と2を乗算をする関数(<code>multiply2</code>)を順番に適用するような関数となっていることが分かるかと思います。</p>



<p class="wp-block-paragraph">このように関数の組み合わせが簡単に実現できてしまいました。これは、関数を引数に取ったり、関数を返却したりできる高階関数のおかげです。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box5"><div class="kaisetsu-box5-title">Note</div>
<p class="wp-block-paragraph">【η簡約（eta reduction）とは】</p>



<p class="wp-block-paragraph">η簡約（エータ簡約）は、関数型プログラミングにおける概念の一つで、関数の定義をより簡潔にするための方法です。具体的には、「関数がただ別の関数に引数を渡すだけの場合、その引数を省略して書くことができる」というルールに基づきます。これにより、コードがシンプルになり、読みやすくなります。</p>



<p class="wp-block-paragraph">例えば、Haskellでの関数定義を考えた際に、もし関数<code>f</code>が引数<code>x</code>を受け取って、そのまま別の関数<code>g</code>に<code>x</code>を渡すだけの場合、つまり<code>f x = g x</code>という形であれば、<code>f</code>を<code>f = g</code>と書き換えることができます。この時、引数<code>x</code>が省略され、より簡潔な形で関数を表現できます。</p>



<p class="wp-block-paragraph">このように、η簡約は「関数が引数を介してただ他の関数を呼び出すだけの場合、その引数を省略しても同じ意味を持つように書ける」という考え方です。これはコードをシンプルに保ち、冗長性を減らすのに役立ちます。</p>
</div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">関数型プログラミング言語における中心的な概念である<span class="marker"><strong>高階関数</strong></span>の基本について解説しました。</p>



<p class="wp-block-paragraph">高階関数は、他の関数を引数として受け取るか、または結果として関数を返すことができ、コードの再利用性や柔軟性を向上させます。今回は、Haskellの簡単な高階関数の実装を通して、高階関数のイメージをつかんでもらいました。</p>



<p class="wp-block-paragraph">高階関数は、関数型プログラミング言語における中心的な概念で、プログラミングにおける表現力を大きく高めるものです。是非考え方をしっかり理解して使いこなしてもらいたいと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-higher-order-functions-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】ラムダ関数（無名関数）の実装方法</title>
		<link>https://haskell-tech.nkhn37.net/haskell-lambda-function-basic/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-lambda-function-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Thu, 08 Feb 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[ラムダ関数]]></category>
		<category><![CDATA[無名関数]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=381</guid>

					<description><![CDATA[Haskellにおけるラムダ関数（無名関数）の実装方法を解説します。 ラムダ関数（無名関数） ラムダ関数とは、関数名がなくても使用できる関数のことです。関数名が不要なことから無名関数とも呼ばれます。 Haskellは、純]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellにおける<span class="marker"><strong>ラムダ関数</strong></span><span class="marker"><strong>（</strong></span><span class="marker"><strong>無名関数</strong></span><span class="marker"><strong>）</strong></span><span class="marker"><strong>の実装方法</strong></span>を解説します。</p>



<h2 class="wp-block-heading">ラムダ関数（無名関数）</h2>



<p class="wp-block-paragraph"><span class="marker"><strong>ラムダ関数</strong></span>とは、関数名がなくても使用できる関数のことです。関数名が不要なことから<span class="marker"><strong>無名関数</strong></span>とも呼ばれます。</p>



<p class="wp-block-paragraph">Haskellは、純粋関数型プログラミング言語であり、関数を主体にプログラミングを行っていきます。関数型プログラミングのパラダイムでは、ラムダ関数は中心的な役割を果たします。これは、関数を第一級オブジェクトとして扱い、関数を他の関数に引数として渡したり、返却値として関数を返したりできるためです。Haskellを含む多くの関数型言語では、ラムダ関数を使ってより表現力豊かで柔軟なコードを記述することが可能です。</p>



<p class="wp-block-paragraph">ラムダ関数を使うことのメリットについては、後述する使い方を見ていただけると分かると思いますが、以下のような点が挙げられます。</p>



<ul class="wp-block-list">
<li>小さな関数をすべて関数名をつけて定義する必要がない。</li>



<li>関数名の衝突を考慮する必要がない。</li>



<li>高階関数の引数としても使用できる。</li>



<li>コードがシンプルになる。</li>
</ul>



<p class="wp-block-paragraph">本記事では、<span class="marker"><strong>Haskellでラムダ関数を実装する方法</strong></span>を例を使いながら説明します。</p>



<h3 class="wp-block-heading">ラムダ関数の基本</h3>



<p class="wp-block-paragraph">Haskellにおけるラムダ関数は以下のように定義します。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box4"><div class="kaisetsu-box4-title">ラムダ関数</div><div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
\引数1 引数2 ... -&gt; 式
</pre></div></div>



<p class="wp-block-paragraph">ラムダ関数は「<code><span style="font-family: Arial;">\</span></code> (バックスラッシュ)」で始まり、関数が受け取る引数を列挙します。なお、「<code><span style="font-family: Arial;">\</span></code> (バックスラッシュ)」であるのはギリシャ文字のλ (ラムダ)が視覚的に類似していることに由来しています。</p>



<p class="wp-block-paragraph">受け取った引数を使った式は「<code>-&gt;</code>」の右側に記載します。ラムダ関数の例としては、具体的には以下のような例になります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; gutter: false; title: ; notranslate">
\x -&gt; 2 * x
</pre></div>


<p class="wp-block-paragraph">ラムダ関数は、通常は高階関数への引数として使用されることが多くなります。ラムダ関数について確認するために、ghci上でその場でラムダ関数を使って使用してみましょう。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; (\x -&gt; 2 * x) 5
10
</pre></div>


<p class="wp-block-paragraph">上記の例では<code>()</code>内で記載した部分がラムダ関数となっています。通常の関数の名称を指定するときと同じで、<code>5</code>を<code>x</code>に受け取り<code>2</code>倍した値を出力しています。</p>



<p class="wp-block-paragraph">以降でラムダ関数の代表的な使用例を紹介します。</p>



<h3 class="wp-block-heading">ラムダ関数の使用例</h3>



<p class="wp-block-paragraph">Haskellでは、ラムダ関数を多様な場面で使用できます。よく使用される例について紹介します。</p>



<h4 class="wp-block-heading">filterとの組み合わせ</h4>



<p class="wp-block-paragraph">Haskellでは、ラムダ関数を使用する際に高階関数と組み合わせることが一般的です。その中でも代表的なものとして、<span class="marker"><strong><code>filter</code></strong></span>という高階関数と組み合わせる例があります。<code>filter</code>関数は、条件に合致するリストの要素を選択します。この関数の型シグネチャは次のようになります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; :t filter
filter :: (a -&gt; Bool) -&gt; &#x5B;a] -&gt; &#x5B;a]
</pre></div>


<p class="wp-block-paragraph">これは、「ある型<code>a</code>の要素を受け取り<code>Bool</code>を返す関数」と「<code>a</code>型のリスト」を受け取り、その条件に合致する「<code>a</code>型のリスト」を返す関数であることを意味しています。</p>



<p class="wp-block-paragraph">例えば、偶数のみをフィルタリングする場合は以下のように書きます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; evenNumbers = filter (\x -&gt; x `mod` 2 == 0) &#x5B;1..10]
ghci&gt; evenNumbers
&#x5B;2,4,6,8,10]
</pre></div>


<p class="wp-block-paragraph">ここで<code>(\x -&gt; x mod 2 == 0)</code>はラムダ関数で、偶数を判定する関数です。このラムダ関数を<code>filter</code>関数に適用することで、指定した<code>1</code>~<code>10</code>のリストから偶数のみを抽出できます。</p>



<p class="wp-block-paragraph">フィルタ条件は、利用場面でよく変わると思いますが、その都度フィルタ関数を名前付きで定義することは非常に負担がかかります。ラムダ関数を用いると、小規模な関数をその場で簡潔に定義でき、コードの柔軟性が高まります。</p>



<p class="wp-block-paragraph">上記は<code>filter</code>という代表的な高階関数の例として紹介していますが、もちろん、その他の高階関数に対しても同様に使用できます。</p>



<h3 class="wp-block-heading">ラムダ関数の適切な利用</h3>



<p class="wp-block-paragraph">ラムダ関数は、Haskellのような関数型プログラミング言語でコードの柔軟性と表現力を高める重要な機能です。ラムダ関数は、一時的な用途や小さな関数を即座に簡潔に記述するのに適しています。ラムダ関数を活用することで、プログラム構造をシンプルに保ちつつ、必要な処理を直接的に表現可能です。</p>



<p class="wp-block-paragraph">しかし、ラムダ関数の使用は、コードの読みやすさや保守性とのバランスを考慮することが重要です。例えば、複数の場所で再利用される可能性がある関数や、その機能が明確に定義されるべき関数の場合は、名前を付けて関数を定義する方が適切です。名前を付けることで関数の目的が明確になり、プロジェクト内での可読性が向上します。</p>



<p class="wp-block-paragraph">大規模なプロジェクトでは、特に可読性と保守性は重要です。多くの開発者がコードを読むため、明確な命名と関数の適切な使用がプロジェクトの成功につながります。ラムダ関数は、利用のバランスを適切にすることで、Haskellプログラムの効率性、可読性、及び保守性を向上させることが可能です。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellにおける<span class="marker"><strong>ラムダ関数（無名関数）の実装方法</strong></span>を解説しました。ラムダ関数は、関数名がなくても使用できる関数のことで、関数名が不要なことから無名関数とも呼ばれます。</p>



<p class="wp-block-paragraph">基本的な記載方法とよく使用される高階関数との組み合わせて使用する方法について例を使って紹介しました。また、関数名をつけて定義するか、ラムダ関数を使うかという点においては、コードの読みやすさや保守性といったバランスを考慮して使用することが重要であることについても説明しました。</p>



<p class="wp-block-paragraph">ラムダ関数は、一時的な用途や小さな関数を即座に記述できるため、関数型プログラミング言語であるHaskellではコードの柔軟性と表現力を高める重要で中心的な機能です。しっかりと理解し、使いこなせるようになってもらえたらと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-lambda-function-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Haskell】再帰関数の実装方法</title>
		<link>https://haskell-tech.nkhn37.net/haskell-recursive-function-basic/</link>
					<comments>https://haskell-tech.nkhn37.net/haskell-recursive-function-basic/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Wed, 31 Jan 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[再帰関数]]></category>
		<guid isPermaLink="false">https://haskell-tech.nkhn37.net/?p=306</guid>

					<description><![CDATA[Haskellを使って再帰関数を実装する方法を解説します。forやwhileといった制御構文がないHaskellにとっては再帰関数は非常に重要な関数です。 Haskellにおける再帰関数 再帰関数とは、自分自身を呼び出す]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Haskellを使って<span class="marker"><strong>再帰関数を実装する方法</strong></span>を解説します。<code>for</code>や<code>while</code>といった制御構文がないHaskellにとっては再帰関数は非常に重要な関数です。</p>



<h2 class="wp-block-heading">Haskellにおける再帰関数</h2>



<p class="wp-block-paragraph"><span class="marker"><strong>再帰関数</strong></span>とは、自分自身を呼び出す関数のことを言います。純粋関数型のプログラミング言語であり、関数を主体にプログラミングを行っていくHaskellにとって再帰関数は非常に重要なものになっています。</p>



<p class="wp-block-paragraph">本記事では、Haskellを使って<span class="marker"><strong>再帰関数を実装する方法</strong></span>を紹介します。</p>



<h3 class="wp-block-heading">Haskellにおける再帰関数の重要性</h3>



<p class="wp-block-paragraph">C/C++、Java、Pythonといった手続き型、オブジェクト指向型のプログラミング言語を学んできた人にとってHaskellを勉強した時に戸惑うことがあります。多くのプログラミング言語では、繰り返しの制御を行うために<code>for</code>や<code>while</code>といった制御構文がありますが、Haskellにはないことです。</p>



<p class="wp-block-paragraph">では、Haskellではどのように繰り返し処理を行うかというと、そこで登場するのが再帰関数です。再帰関数で表現することについては理解しにくい部分かと思いますが、Haskellを学んで慣れていくことで非常に美しい直感的なコードを書くことができるようになります。</p>



<p class="wp-block-paragraph">本記事では、<span class="marker"><strong>Haskellで再帰関数を実装する方法</strong></span>について紹介していきます。</p>



<h3 class="wp-block-heading">再帰関数の基本</h3>



<p class="wp-block-paragraph">再帰関数とは、どういったものでしょうか。例えば再帰関数の代表的な例として$n!=n\cdot(n-1)\cdot&#8230;\cdot2\cdot1$といった階乗を求める関数があります。なお、$0!=1$です。</p>



<p class="wp-block-paragraph">Haskellで階乗を求める関数を実装する場合は以下のようになります。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- 階乗関数
factorial :: Integer -&gt; Integer
factorial 0 = 1
factorial n = n * factorial (n-1)
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行例】
ghci&gt; factorial 1
1
ghci&gt; factorial 2
2
ghci&gt; factorial 3
6
ghci&gt; factorial 4
24
ghci&gt; factorial 5
120
</pre></div>


<p class="wp-block-paragraph">Haskellの再帰関数を記述するときに非常に重要になってくるのは、パターンマッチという機能です。パターンマッチについては「<a href="https://haskell-tech.nkhn37.net/haskell-function-pattern-match/" target="_blank" rel="noreferrer noopener">関数におけるパターンマッチ</a>」でまとめていますので参考にしてください。</p>



<p class="wp-block-paragraph">階乗関数では、$0!=1$です。このパターンを示しているのが<code>factorial 0 = 1</code>の部分です。$n$番目の値を処理する場合には、$n$と$n-1!$をかけることになるので<code>factorial n = n * factorial (n-1)</code>となります。<code>n</code>に値を入れてみて自分で展開してみると分かりやすいでしょう。</p>



<div class="wp-block-jin-gb-block-box concept-box2">
<p class="wp-block-paragraph">上記コードは負の数に対するエラーなどは考慮していません。今回は再帰部分に焦点を当てるために除外してシンプルにしていますが、適切な関数として考慮する場合には<code>Either</code>型クラスを利用した実装等を検討する必要があることに注意が必要です。詳細説明は省略しますが、例えば以下のような実装例が考えられます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
factorial&#039; :: Integer -&gt; Either String Integer
factorial&#039; n
    | n &lt; 0     = Left &quot;Error: Negative numbers are not allowed.&quot;
    | n == 0    = Right 1
    | otherwise = case factorial&#039; (n - 1) of
        Left err -&gt; Left err
        Right res -&gt; Right (n * res)
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行例】
ghci&gt; factorial&#039; 5
Right 120
ghci&gt; factorial&#039; (-1)
Left &quot;Error: Negative numbers are not allowed.&quot;
</pre></div></div>



<p class="wp-block-paragraph">階乗関数は他の言語でも再帰で実装されることがあるので、もう少し違う例を見てみましょう。非常に簡単ですが、リストの要素を順番に取り出して値を2倍する関数を考えます。この時、他の言語では<code>for</code>文で要素を一つずつ取り出して2倍していくという方法をとるかもしれません。しかし、Haskellでは<code>for</code>文などの繰り返し制御構文がないため、こういった対応ができません。Haskellでは以下のように関数を定義します。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- リストを2倍する関数
doubleList :: &#x5B;Integer] -&gt; &#x5B;Integer]
doubleList &#x5B;] = &#x5B;]
doubleList (x:xs) = (2 * x) : doubleList xs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
【実行例】
ghci&gt; doubleList &#x5B;1, 2, 3, 4, 5] 
&#x5B;2,4,6,8,10]
</pre></div>


<p class="wp-block-paragraph">リストを2倍するには「先頭から1要素取り出して2倍し、残りのリストの各要素を2倍したリストと結合する」と考えてみます。この処理の終了条件を考えていくと、要素を取り出していった場合には最後には空リスト<code>[]</code>が残ります。この空リスト<code>[]</code>に対する結果は、空リスト<code>[]</code>でよいでしょう。この部分が<code>doubleList [] = []</code>となります。</p>



<p class="wp-block-paragraph">では、繰り返しプロセス「先頭から1要素取り出して2倍し、残りのリストの各要素を2倍したリストと結合する」の定義を考えてみます。Haskellでは<code>(x:xs)</code>というパターンマッチで先頭要素<code>x</code>と残りのリスト<code>xs</code>を取得することができます。取り出した先頭要素を2倍し、残りのリストを2倍したリストと結合します。この部分が「<code>doubleList (x:xs) = (2 * x) : doubleList xs</code>」になります。リストの結合は「<code>:</code>」で実行でき、コンスと呼ばれます。</p>



<p class="wp-block-paragraph">実行例を見ても分かるようにこのように実装することでリストを2倍したリストを取得できていることが分かります。</p>



<p class="wp-block-paragraph">上記の例を参考にして再帰のプログラミングをする際の考え方を整理してみると以下のようになります。</p>



<div class="wp-block-jin-gb-block-box-with-headline kaisetsu-box4"><div class="kaisetsu-box4-title">再帰関数定義の考え方</div>
<ol class="wp-block-list">
<li>再帰プロセスの終了条件を決め、終了時の結果を定義する</li>



<li>再帰の繰り返しプロセスを決めて定義する</li>
</ol>
</div>



<ol class="wp-block-list"></ol>



<p class="wp-block-paragraph">１の手順は、<code>factorial</code>の場合は「<code>factorial 0 = 1</code>」、<code>doubleList</code>の場合は「<code>doubleList [] = []</code>」に該当します。そして、２の手順がそれぞれ「<code>factorial n = n * factorial (n-1)</code>」や「<code>doubleList (x:xs) = (2 * x) : doubleList xs</code>」になります。</p>



<p class="wp-block-paragraph">Haskellは宣言的に関数を定義するというのが特徴的で、処理の内容を捉えやすい理由です。「先頭から1要素取り出して2倍し、残りのリストの各要素を2倍したリストと結合する」ということが、まさに「<code>doubleList (x:xs) = (2 * x) : doubleList xs</code>」に表現されています。</p>



<h3 class="wp-block-heading">多くの場合は便利な高階関数を利用する</h3>



<p class="wp-block-paragraph">上記では、再帰関数の定義の考え方について紹介してきました。しかし、Haskellでのプログラミングをする場合は、多くの場合は便利な高階関数を使用します。高階関数とは、関数を引数として受け取ったり、関数自体を返却したりする関数のことを言い、関数型プログラミングのパラダイムでよく登場します。</p>



<p class="wp-block-paragraph">例えば、上記で紹介した<code>doubleList</code>関数は、<code>map</code>関数という高階関数を使って以下の<code>doubleList'</code>関数のように書き換えることができます。</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: haskell; title: ; notranslate">
-- リストを2倍する関数
doubleList&#039; :: &#x5B;Integer] -&gt; &#x5B;Integer]
doubleList&#039; xs = map (*2) xs
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
ghci&gt; doubleList&#039; &#x5B;1, 2, 3, 4, 5]
&#x5B;2,4,6,8,10]
</pre></div>


<p class="wp-block-paragraph">再帰関数での実装例と比べるとシンプルになっていることが分かるかと思います。<code>map</code>関数は、関数とリストを受け取ってリスト要素のそれぞれに受け取った関数を適用した結果リストを返してくれます。Haskellでは<code>(*2)</code>は2倍するという関数を意味します。この関数とリスト<code>xs</code>を引数に渡すとすべての要素に適用した結果リストを返してくれます。</p>



<p class="wp-block-paragraph">他にも代表的な高階関数として要素を抽出する<code>filter</code>や畳み込みのための<code>foldl</code>、<code>foldr</code>といった関数等がありますので、そういった関数をまずは使うことを考えるのが一般的です。これらの高階関数については、また別途まとめてみようかと思います。</p>



<p class="wp-block-paragraph">なお、より複雑な処理などを検討する場合には自分で再帰関数を書くべき時もあるため、考え方をよく理解しておいてもらうと良いかと思います。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Haskellを使って<span class="marker"><strong>再帰関数を実装する方法</strong></span>を解説しました。<code>for</code>や<code>while</code>といった制御構文がないHaskellにとっては再帰関数は非常に重要な関数となっています。</p>



<p class="wp-block-paragraph">階乗関数やリストを2倍するといった簡単な例を使って再帰関数の定義方法について紹介しました。また、実際には繰り返し処理に該当するような再帰処理についても、<code>map</code>等のHaskellで既に定義されている便利な高階関数を使うことができることも説明しました。</p>



<p class="wp-block-paragraph">Haskellでは、再帰関数は非常に重要な関数であるので、是非考え方や実装方法について理解してもらえたらと思います。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-haskell-tech wp-block-embed-haskell-tech"><div class="wp-block-embed__wrapper">
<a href="https://haskell-tech.nkhn37.net/haskell-introduction/" class="blog-card"><div class="blog-card-hl-box"><i class="jic jin-ifont-post"></i><span class="blog-card-hl"></span></div><div class="blog-card-box"><div class="blog-card-thumbnail"><img src="https://haskell-tech.nkhn37.net/wp-content/uploads/2024/01/Haskell入門-320x180.jpg" class="blog-card-thumb-image wp-post-image" alt="Haskell入門" width ="162" height ="91" /></div><div class="blog-card-content"><span class="blog-card-title">Haskell入門</span><span class="blog-card-excerpt">純粋関数型言語であるHaskellの入門編となる記事についてまとめます。Haskellで基本となる項目を中心に解説しているページへのリンク集です。...</span></div></div></a>
</div></figure>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://haskell-tech.nkhn37.net/haskell-recursive-function-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: haskell-tech.nkhn37.net @ 2026-06-11 06:21:31 by W3 Total Cache
-->