1. ホーム
  2. functional-programming

[解決済み] 関数型プログラミングで時間関数が存在するのはなぜですか?

2022-03-15 02:11:32

質問

正直なところ、私は関数型プログラミングについてあまり詳しくありません。あちこちで読んでいるうちに、関数型プログラミングでは、関数は何度呼び出されても、同じ入力に対して同じ出力を返すということを知りました。数学の関数が、関数式に含まれる入力パラメータが同じ値であれば、同じ出力に評価されるのと全く同じです。

例えば、こんなことを考えてみてください。

f(x,y) = x*x + y; // It is a mathematical function

を何度使っても f(10,4) の場合、その値は常に 104 . 従って、あなたが f(10,4) で置き換えることができます。 104 のように、式全体の値を変更することなく、その値を変更することができます。このプロパティは、以下のように呼ばれます。 参照透過性 という式があります。

ウィキペディアにあるように( リンク ),

逆に、関数型コードでは、関数の出力値は関数に入力された引数だけに依存するので、引数xに同じ値を指定して関数fを2回呼び出すと、2回とも同じ結果f(x)が得られます。

を返す)時間関数は可能ですか? 現在の は関数型プログラミングに存在するのでしょうか?

  • もしそうなら、どうして存在できるのでしょうか?関数型プログラミングの原則に反しないのでしょうか?特に違反するのは 参照透過性 これは、私が正しく理解していれば、関数型プログラミングの特性の1つです。

  • あるいは、もしそうでないとしたら、関数型プログラミングでどうやって現在時刻を知ることができるのでしょうか?

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

他の説明としては、以下のようになります。 機能 は現在の時刻を取得することができますが(常に変化しているため)。 アクション は現在の時刻を取得することができます。例えば、次のように言ってみましょう。 getClockTime を表す定数(ヌル関数でも可)です。 アクション 現在時刻を取得する。これは アクション は、いつ使っても同じなので、まさに定数です。

同じように、例えば print は、ある時間表現を受け取り、それをコンソールに表示する関数です。純粋な関数型言語では関数呼び出しが副作用を持つことはできないので、代わりに、タイムスタンプを受け取って アクション をコンソールに表示する。繰り返しになりますが、これは本物の関数です。なぜなら、同じタイムスタンプを与えれば、同じ アクション を毎回印刷する。

さて、現在時刻をコンソールに表示するにはどうしたらよいでしょうか。さて、2つのアクションを組み合わせる必要があります。では、どうすればいいのでしょうか?単に getClockTime から print というのも、printはアクションではなくタイムスタンプを期待しているからです。しかし、演算子があることは想像できます。 >>= は、どのような を結合する。 タイムスタンプを取得するアクションと、タイムスタンプを引数に取ってそれを表示するアクションの2つです。これを先ほどのアクションに適用すると、結果は...なんと...現在時刻を取得してそれを表示する新しいアクションになるのです。ちなみに、これはHaskellで行われている方法と全く同じです。

Prelude> System.Time.getClockTime >>= print
Fri Sep  2 01:13:23 東京 (標準時) 2011

つまり、概念的にはこのように捉えることができるのです。純粋な関数型プログラムは、I/Oを行わずに アクション そして、それをランタイムシステムが実行する。このとき アクション は毎回同じですが、実行した結果は実行時の状況によって異なります。

他の説明より分かりやすかったかどうかは分かりませんが、こうやって考えると助かることもあります。