Betrachten Sie das Problem der Erzeugung von Strings aus einer Reihe von möglichen Strings, so dass einmal eine Zeichenfolge ausgewählt wird, kann es nicht erneut wiederholt werden. Für diese Aufgabe möchte ich QuickCheck
's Gen
Funktionen verwenden.Erzeugen von zufälligen Strings aus einem String-Pool mit QuickCheck
Wenn ich auf den Typ der Funktion schaue, die ich versuche zu schreiben, sieht es ziemlich wie eine Zustands-Monade aus. Da ich eine andere Monade verwende, nämlich Gen
, innerhalb der State Monade. Ich schrieb meinen ersten Versuch mit StateT
.
arbitraryStringS :: StateT GenState Gen String
arbitraryStringS =
mapStateT stringGenS get
wo:
newtype GenState = St {getStrings :: [String]}
deriving (Show)
removeString :: String -> GenState -> GenState
removeString str (St xs) = St $ delete str xs
stringGenS :: Gen (a, GenState) -> Gen (String, GenState)
stringGenS genStSt =
genStSt >>= \(_, st) ->
elements (getStrings st) >>= \str ->
return (str, removeString str st)
Etwas, das mich an dieser Implementierung die Tatsache ist beunruhigt, dass ich nicht das erste Element stringGenS
verwenden. Zweitens ist mein Endziel, einen Zufallsgenerator für JSON-Werte zu definieren, die einen Ressourcenpool verwenden (der nicht nur Strings enthält). Mit StateT
führte mich „Stateful“ Varianten von QuickCheck
‚s elements
, listOf
usw.
Ich habe mich gefragt, zu implementieren, ob es einen besseren Weg, dies zu erreichen, oder eine solche Komplexität ist inhärent definieren Stateful Varianten bestehender Monaden.
Ich würde es anders machen - um die erzeugten 'Strings' zu speichern - oder zumindest die Seeds und vergleichen jeden Seed/generierten String für die Mitgliedschaft in einem' Set' von Seeds/'String'. – epsilonhalbe
eine andere Wahl könnte UUIDs verwenden, um "höchstwahrscheinlich" eindeutige Strings zu erzeugen, wenn Sie nur eine endliche Menge von Strings haben - Sie haben schließlich keine Strings mehr, können Sie mit großen Sets arbeiten, aber trotzdem werden Sie laufen in doppelte Strings - wenn Sie "echte Einzigartigkeit" brauchen, würde ich mit einem Basissatz + einem unendlichen Satz wie die natürlichen Zahlen gehen und diesen kombinieren. – epsilonhalbe
Es ist wichtig, dass die Zeichenfolgen aus dem Ressourcenpool stammen. Dies kann verwendet werden, um Tests unter Verwendung von Daten zu erzeugen, die in einer Datenbank vorhanden sind. –