この 古い質問 は、関数型プログラミングではFPの関数は純粋/べき等であり、副作用のない呼び出しの数に関係なく同じ値を返すため、「真の」ランダム性を実現できないことを示しています。
しかし、それが本当なら、FPは、システムに入る前にユーザーに質問するために、キャプチャやパズルをランダムに選ぶなどの問題にどのように適用できますか?
関数の中にシードとしてシステム時間を取ることを考えました。しかし、それは外部の状態に依存しています。
誰かがHaskell/Clojureなどのコードスニペットでそれを実証していただけませんか?
真の乱数について話しているのか、疑似乱数について話しているのかを指定していないので、あなたの質問は少し不明確なので、私は両方に答えます。
あなたは関数型プログラムが真の乱数を生成できないことは正しいです。しかし、どちらも命令型プログラムにはできません。コンピューターは、Cプログラムを実行しているかHaskellプログラムを実行しているかに関係なく、依然として確定的なマシンです。
疑似乱数は、疑似乱数ジェネレーター(別名PRNG)によって生成されます。 PRNGは、他のアルゴリズムと同様の単なるアルゴリズムです。それらは関数型言語でも表現でき、命令型言語でも表現できます。
したがって、乱数に関しては、関数型言語と命令型言語の間に違いはありません。 両方は疑似乱数を計算でき、どちらもは真の乱数を計算できます(まったく計算できないため)。
FP=関数は純粋/べき等であり、呼び出しの数に関係なく同じ値を返すため、副作用なしで「真の」ランダム性を実現できません。
繰り返しますが、命令型プログラミングでも同じことが当てはまります。同じシード番号でsrand
を呼び出すと、毎回Rand
から同じ疑似乱数シーケンスが確実に得られます。
真のランダム性を得る唯一の方法は、I/Oを使用することです。しかし、関数型言語は、I/Oモナド(またはRandom
モナドのようなより専門的なもの)、線形型、ワールドタイプ、エフェクトタイプ、エフェクトシステムのいずれであっても、I/Oをうまくモデリングできます。または、Scala、ML、Clojure、F♯のように、単純にそれらを許可し、プログラマーが間違いを犯さないように信頼することでそれを行います。
つまり、言い換えれば、乱数について質問することは意味がありません特に。 A PRNGは単なる関数なので、関数型プログラミングを使用して疑似乱数を処理する方法を尋ねる場合は、関数型プログラミングを使用して関数を処理する方法を尋ねる必要があります、PRNGについて特別なものなしがあるため、これは単なる関数です。真のランダムネスは単なるI/Oなので、繰り返しますが、それらについて尋ねることは意味がありません特に。
FPで関数を記述できることを受け入れる場合は、FPでPRNGを記述できることも受け入れる必要があります。また、時計の読み取り、ユーザーからの入力の読み取り、ファイルの読み取り、データベースへのアクセス、Webへのアクセスなどが可能であることを受け入れる場合は、真の乱数を読み取ることができることも受け入れる必要があります。 (たとえば、Unixでは、たとえば、デバイスドライバーは通常ファイルとして公開され、真の乱数デバイスは通常、ユーザーが読み取ったファイルとして公開されます。そして、真の乱数を提供するWebサービスがあります。)
乱数ジェネレータの要点は、入力の決定関数であるnotである値を返すことです。
したがって、「乱数関数」は、矛盾しています。 I/Oと同等ではなく、確定的システムの一部として純粋に関数としてモデル化できます。
私たちが関数型言語で行うことは、単に非関数的で非決定的なメソッド呼び出しを実装することです。これは関数のように見え、関数構文のガーブを持ち、関数としてまとめられます(そして呼び出されたり評価されたり、使用された結果は、他の関数と比較して決定論的な順序で使用されます)が、実際には関数ではありません(その出力は入力に関連しないため)-そして、それに依存するプログラム全体は関数ではなくなります(なぜならプログラムはその入力に従って決定的に実行されません)。
ランダム性は、他の種類の入力と同じように処理されます。
ランダムは、ハードウェアクロックの状態を読み取るようなものです。これは、カメラの状態を読み取ってコンピューターユーザーのプロフィール写真を撮るようなもの、または特定のファイルのコンテンツを読み取るようなものです。ランダムは、特別な種類の入力です。
理論的には、ランダム性を他の種類の入力とは異なる方法で処理する必要があります。たとえば:セキュリティのため。そして、純粋に関数型プログラミングの理論は、そのニーズに応えることができます。しかし実際には、この方向性は追求されていない。ソフトウェアエンジニアリングの能力が不足しているというだけの理由で、さらに重要なセキュリティニーズは実際にはまだ対処されていません。
このトピックは、Web上の多くの資料で説明されています。ここでStackExchangeについて説明する場合は、独自の質問に値します。
純粋な関数は、ランダムに依存する最終的な具体的な結果ではなく、小さなアルゴリズムのように、[おそらく複合]アクションを返します。ランダムな値を取得します。それを使用して他のアクションを計算し、その他のアクションを実行します。純粋な関数は、プログラムが何をすべきかを表し、説明する決定論的な値のみを返します。非確定性の「汚い」問題であるIOをランタイムシステムに転送します。純粋な関数は何もせず、何をすべきかを計算して[返す]だけです。