Generiert eine zufällige ganze Zahl in einem Bereich in Haskell ohne Samen
Wie kann ich eine Zufallszahl erzeugen in Haskell die aus einem Bereich (a, b) ohne Saatgut?
Die Funktion muss Int zurückgeben und nicht ein E /a-Int.
Ich habe eine Funktion X, die dauert und Int und andere Argumente-und Ausgänge etwas, was nicht IO.
Wenn dies nicht möglich ist, wie kann ich erstellen ein samenkorn mit der Zeit, die Bibliothek und das generieren einer zufälligen Zahl im Bereich mit den mkStdGen ?
Jede Hilfe wäre wirklich zu schätzen.
- stackoverflow.com/a/2738824/570689 - nette Antwort für eine ähnliche Frage
- Es klingt wie das beste, was Sie hoffen kann, ist
randomInt lo hi = lo
oder etwas in der Art. Ohne irgendeine Art von Samen oder IO die Funktion wieder den gleichen Wert jedes mal. Und die Untergrenze ist so zufällig wie jeder andereInt
. 🙂 - "Wer meint, dass sich der rechnerische Methoden zur Herstellung von Zufallszahlen ist, natürlich, in einem Zustand der Sünde." Zugeschrieben John Von Neumann in Knuth, D. The Art of Computer Programming, vol. 2, p. 1 (1981).
- Ich glaube, der beste Weg, um eine zufällige Zahl in Haskell ohne IO-oder seed-Wert ist mit eine Funktion wie diese.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer Funktion zurückgeben kann eine
Int
ohneIO
, es sei denn, es ist eine Reine Funktion, d.h. die gleiche Eingabe immer die gleiche Ausgabe. Dies bedeutet, dass wenn Sie ein zufällige Nummer, ohneIO
, werden Sie brauchen, um einen Samen als argument.Wenn Sie sich dazu entschließen, ein samenkorn, es sollte vom Typ
StdGen
, und Sie könnenrandomR
zu generieren, die eine Reihe von es. VerwendennewStdGen
zum erstellen einer neuen Samen (diese werden inIO
).Ergebnis
randomR
ist ein Tupel, wo das erste element ist der zufällige Wert, und die zweite ist eine neue Saatgut für die Erzeugung von mehr-Werten.Ansonsten können Sie
randomRIO
um eine Zufallszahl direkt in dieIO
Monade, mit allenStdGen
Sachen kümmern für Sie:import System.Random
!Ohne Rückgriff auf alle Arten von unsicheren Praktiken, ist es nicht möglich, eine solche Funktion zu haben, geben
Int
eher als TypIO Int
oder etwas ähnliches. Funktionen (oder, in diesem Fall, Konstanten) vom TypInt
rein sind, was bedeutet, dass jedes mal, dass Sie "berufen" ist, die Funktion (abrufen des Werts der Konstanten) Sie werden garantiert, um den gleichen Wert "zurückgegeben".Wenn Sie möchten, um einen anderen, zufällig gewählten Wert, der zurückgegeben wird, bei jedem Aufruf, werden Sie brauchen, um die Nutzung
IO
-Monade.In einigen Fällen, möchten Sie vielleicht einen einzigen zufällig erzeugten Wert für das gesamte Programm, das heißt, einer, der, aus der Sicht des Programms verhält sich, als wäre es ein reiner Wert. Jedes mal, wenn die Abfrage den Wert in der gleichen Ausführung des Programms erhalten Sie den gleichen Wert zurück. Als das ganze Programm ist im wesentlichen eine
IO
-Aktion könnte man dann zu erzeugen, dass der Wert einmal, und übergeben Sie es herum, aber das kann sich ein wenig ungeschickt. Man könnte argumentieren, dass, in dieser situation, es ist immer noch sicher zu zuordnen, wird der Wert mit einer top-level-Konstante vom TypInt
und verwendenunsafePerformIO
zu konstruieren, die Konstante:oder
Das Ergebnis wird dann der Typ
IO whateverYourFunctionXReturns
.Wenn Sie
import Control.Applicative
Sie sagen könnenoder
dem finden Sie klarere
Beachten Sie, dass Sie eine unendliche Liste von zufälligen Werte mit Hilfe der IO-Monade und verwenden, die
[Int]
im nicht-IO-Funktionen. Auf diese Weise müssen Sie nicht haben, um zu tragen die Samen zusammen mit Ihnen, aber immer noch brauchen, um die Liste natürlich. Glücklicherweise gibt es eine fülle von list processing-Funktionen zu vereinfachen, wie threading-und Sie können nochState
Monade in komplizierten Fällen.Beachten Sie auch, dass Sie können leicht umwandeln ein IO Int zu Int. Wenn foo erzeugt ein IO Int, und die bar nimmt einen Int als parameter und gibt ein nicht-IO-Wert, wird Folgendes tun:
Oder mit do-notation:
Oder mit
fmap
(Monaden sind funktoren, und<$>
ist ein infix-version vonfmap
):Ich verwendet SipHash für diesen Zweck
lese-und drop 8 und zeigen Sie dem Zweck dienen, fallen, newtype, die nicht (oder nicht, wenn ich umgesetzt) unterstützt alle casting
jetzt willst du ein Int in einer Reihe. Integer ist einfacher aber:
natürlich erhalten Sie noch die gleiche Nummer für die gleichen Argumente, jedes mal, so müssen Sie variieren Sie, dh Sie passieren noch um Argumente, nur keine Werte zu. Ob das bequemer ist, als eine Monade, hängt (für meinen Zweck)
dies ist, wie ich sicher Argumente (speziell die [Word8] - argument) würde immer anders sein: