1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「状態の変化」が禁止されている言語でどうやって繰り返し処理するの?【Haskellと再帰関数】

Last updated at Posted at 2025-03-05

記事の内容

「副作用がないこと=状態を変化させないこと」と繰り返し処理を両立させたい。どうすればいいの?

Haskellのような純粋関数型プログラミングにおいて、「副作用がないこと=状態を変化させないこと」と再帰がどのように関係しているのか、整理しましょう。

関数型言語の初心者向けの内容です。

専門家と高校生の会話形式でまとめています。


目次

  1. Haskellにおける「副作用がないこと」と再帰の関係性
  2. プログラムにおける「状態」の定義
  3. プログラムにおける「状態の変化」の定義
  4. なぜ再帰関数は状態を変化させないのか 再帰関数のしくみ
  5. Haskellの再帰実行中に生成される新しい値たちの管理方法
  6. まとめ
  7. 参考文献

1. Haskellにおける「副作用がないこと」と再帰の関係性

高校生:

「副作用がないってどういう意味なんですか?そして、なぜ再帰がその実現に役立つのでしょうか?」

専門家:

「Haskellでは、一度計算された値は決して変わらず、変数の値を直接更新することがありません。つまり、プログラム実行中に『状態』が変わることがなく、その結果、副作用が生じません。再帰は、この性質を保ちながら繰り返し処理を行うための重要な手法です。再帰を使えば、状態を直接更新するのではなく、前の状態に基づいて新しい状態を『生成』できます。」


2. プログラムにおける「状態」の定義

高校生:

「状態って具体的に何を意味するんですか?」

専門家:

「プログラムにおける『状態』とは、ある瞬間にプログラムが保持しているすべての情報、つまり変数やデータの集合のことです。これは、『今、この瞬間にプログラムがどんな値を保持しているか』というスナップショットのようなものです。命令型プログラミングでは、この状態が随時更新されますが、Haskellのような純粋関数型言語では、状態は一度決定されたら変わらない不変のものとして扱われます。」


3. プログラムにおける「状態の変化」の定義

高校生:

「じゃあ、『状態の変化』とは何ですか?」

専門家:

「状態の変化とは、プログラム内で保持される情報が更新されることです。

  • 命令型プログラミングでは、変数の再代入により状態が変わります。
  • 関数型プログラミングでは、既存の値を直接更新するのではなく、前の状態をもとに『新しい状態』が計算され、返されます。」

4. なぜ再帰関数は状態を変化させないのか 再帰関数のしくみ

高校生:

「再帰は、なぜ状態を変化させないのに処理を繰り返せるんですか?」

専門家:

「再帰は、関数が自分自身を呼び出すことで繰り返し処理を実現します。再帰の核心は、引数として新しい状態を渡すことです。具体例を見ましょう。」

具体例: 階乗計算

factorial :: Integer -> Integer
factorial 0 = 1                    -- 基底条件
factorial n = n * factorial (n - 1)  -- 再帰呼び出し:nから新しい状態(n - 1)を生成

「nの値は再帰呼び出しのたびに減少、つまり、更新されていると解釈してはいけません。各関数呼び出しは独立して計算されるため、関数を呼び出すたびに新しい状態を生成しています。つまり、古い状態はそのまま残っているという点が純粋性を保っています。」

高校生:

「つまり、再帰では前の状態を変更するのではなく、常に『新しい状態』を作り出すということですね。」

専門家:

「その通りです。これがHaskellでの不変性(immutability)を保ちながら、複雑な計算を実現する方法です。」

5. Haskellの再帰実行中に生成される新しい値たちの管理方法

専門家:

「Haskellでは、以下の仕組みによって新しい値が管理されています。」

  • グラフリダクション
    Haskellは、プログラムの評価をグラフの縮約として扱います。これにより、同じ計算が繰り返されないようにします。

  • 遅延評価とサンク (Thunk)
    必要になるまで値を計算せず、必要になったときに初めて評価します。評価済みの結果はキャッシュされます。

  • コールスタックと最適化
    Haskellのコンパイラは、再帰呼び出しが深くならないように最適化(例えば末尾再帰最適化)を行います。


6. まとめ

  • 副作用がないとは:
    値が不変で、同じ入力に対して常に同じ出力を返すこと。
  • 再帰の利点:
    再帰は今ある状態を直接変更せず、新しい状態を生成する。
  • Haskellの管理方法:
    グラフリダクション、遅延評価、最適化によって効率的に値を管理。

7. 参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?