純粋な関数はグローバル状態を読み取ることができますか?
-
03-07-2019 - |
質問
注意:「純粋」とは機能、「純粋な仮想」を意味するものではありません
これ
関数が「読む」場合いくつかのグローバルな状態、それはそれを自動的に不純にしますか?それとも他の要因に依存しますか?
自動的に不純になる場合は、その理由を説明してください。
他の要因に依存する場合、それらが何であるか説明してください。
解決
「純粋」 functionは、結果がその入力引数にのみ依存する関数です。それ以外のものを読み取る場合、それは純粋な関数ではありません。
他のヒント
特定の特殊なインスタンスでは、はい。たとえば、関数によってのみ読み書きされる計算済みの値のグローバルキャッシュがある場合、出力は入力のみに依存するという意味では数学的に純粋ですが、純粋ではありません厳密な意味で。例:
static int cache[256] = {0};
int compute_something(uint8_t input)
{
if(cache[input] == 0)
cache[input] = (perform expensive computation on input that won't return 0);
return cache[input];
}
この場合、他の関数がグローバルな cache
に触れない限り、外部のグローバルな状態に技術的に依存していても、数学的に純粋な関数のままです。ただし、この状態は単なるパフォーマンスの最適化であり、それなしでも同じ計算を実行しますが、よりゆっくりです。
純粋な式を作成するには、純粋な関数が必要です。定数式は定義上純粋です。
したがって、グローバルな「状態」が変わらない場合は問題ありません。
参照透過性も参照してください:
より微妙な例は、グローバル変数(または動的スコープ変数、レキシカルクロージャー)を使用して結果を計算するのに役立つ関数の例です。この変数はパラメーターとして渡されないため、変更できるため、パラメーターが同一であっても、その後の関数呼び出しの結果は異なる場合があります。 (純粋な関数型プログラミングでは、破壊的な割り当ては許可されていません。したがって、グローバル(または動的スコープ)変数を使用する関数は、これらの変数を変更できないため、参照的に透過的です。)
たとえば、Haskellでは、不純な側で乱数の無限リストを作成し、そのリストを純粋な関数に渡すことができます。実装は、純粋関数が必要な場合にのみ使用する次の番号を生成しますが、関数はまだ純粋です。