1. ホーム
  2. javascript

[解決済み] これは純関数ですか?

2022-07-29 21:31:23

質問

ほとんどの場合 ソース は、次の2つの特性を持つものとして純粋関数を定義しています。

  1. その戻り値は同じ引数に対して同じである。
  2. 評価には副作用がない。

気になるのは最初の条件です。ほとんどの場合、判断は簡単です。次のようなJavaScriptの関数を考えてみてください(表示されている この記事 )

ピュアです。

const add = (x, y) => x + y;

add(2, 4); // 6

不純です。

let x = 2;

const add = (y) => {
  return x += y;
};

add(4); // x === 6 (the first time)
add(4); // x === 10 (the second time)

2番目の関数がそれ以降の呼び出しで異なる出力をすること、それによって最初の条件に違反することは容易に理解できます。したがって、それは不純物です。

この部分はわかった。


さて、私の質問のために、ドルでの与えられた金額をユーロに変換するこの関数を考えてみましょう。

(編集 - 使用する const を1行目で使っています。使用されている let をうっかり使ってしまいました(笑)。

const exchangeRate =  fetchFromDatabase(); // evaluates to say 0.9 for today;

const dollarToEuro = (x) => {
  return x * exchangeRate;
};

dollarToEuro(100) //90 today

dollarToEuro(100) //something else tomorrow

為替レートをDBから取得し、それが毎日変化すると仮定します。

さて、この関数を何度呼び出しても 今日 を何度呼び出しても同じ出力が得られます。 100 . しかし、明日には違う出力が得られるかもしれません。これが最初の条件に違反するかどうかはわかりません。

つまり、関数自体は入力を変化させるロジックを含んでいませんが、将来変化するかもしれない外部の定数に依存しているのです。この場合、毎日変更されることは絶対確実です。他のケースでは、それは起こるかもしれないし、起こらないかもしれません。

このような関数を純粋関数と呼ぶことはできるのでしょうか。もし答えがNOであれば、どのようにリファクタリングして1つにすることができるでしょうか?

どのように解決するのですか?

この dollarToEuro の戻り値は引数ではない外部変数に依存します。したがって、この関数は不純物です。

答えがNOの場合、どのように関数をリファクタリングすれば純粋になるのでしょうか?

一つの選択肢は exchangeRate . この方法では、引数が毎回 (something, somethingElse) である場合、出力は 保証 であることが something * somethingElse :

const exchangeRate =  fetchFromDatabase(); // evaluates to say 0.9 for today;

const dollarToEuro = (x, exchangeRate) => {
  return x * exchangeRate;
};

なお、関数型プログラミングでは let - を使うべきです。 const を使ってください。