Aufbau einer Liste in Haskell


Tag

Ich möchte eine Liste zufälliger Ganzzahlen ohne Duplikate erstellen. Als ersten Schritt habe ich eine Funktion, die eine Liste von n Zufallsstichproben erstellt. Wie schreibt man dies auf eine eher Haskell-idiomatische Weise, bei der keine leere Liste übergeben werden muss, um die Liste zu starten? Ich bin sicher, ich vermisse etwas Grundlegendes und Grundlegendes.

-- make a list of random integers.
-- takes a size, and an empty list.
-- returns a list of that length of random numbers.
f :: Int -> [Int] -> IO [Int]
f l xs | length xs >= l = return (xs)
f l xs = do
  r <- randomRIO (1, 40) :: IO Int
  f l $ r : x

Verwendung:

*Main> f 6 []
[10,27,33,35,31,28]

Letztendlich wird diese Funktion gefiltert, um nach doppelten Einfügungen zu suchen, aber das ist eine separate Frage. Dies mag zwar wie Hausaufgaben aussehen, ist es aber nicht, aber Teil meines eigenen Versuchs, die staatliche Monade, wie sie für die Zufallszahlengenerierung verwendet wird, in den Griff zu bekommen und festzustellen, dass ich an einem viel früheren Ort festsitze.

Bakuriu

Nun, Sie können die Ausgabe des rekursiven Aufrufs bearbeiten:

f :: Int -> IO [Int]
f 0 = return []
f n = do
    r <- randomRIO (1, 40)
    xs <- f (n-1)
    return $ r : xs

Beachten Sie jedoch, dass es wichtig ist, dass die Operation, die Sie für das Ergebnis ausführen, schnell ist. In diesem Fall r : xsist die Zeit konstant. Wenn Sie jedoch die letzte Zeile durch (sagen wir) ersetzen:

    return $ xs ++ [r]

Dies würde die Komplexität der Funktion von linear zu quadratisch ändern, da bei jedem ++Anruf die gesamte Sequenz zuvor generierter Nummern gescannt werden muss, bevor die neue angehängt wird.


Sie können jedoch einfach Folgendes tun:

f n = sequence $ replicate n (randomRIO (1, 40))

replicateErstellt eine [IO Int]Liste der Länge nvon randomRIOAktionen und sequencenimmt eine [IO a]und verwandelt sie in eine, IO [a]indem alle Aktionen der Reihe nach ausgeführt und die Ergebnisse gesammelt werden.

Noch einfacher können Sie replicateMdie bereits gewünschte Funktion verwenden:

import Control.Monad(replicateM)

f n = replicateM n (randomRIO (1, 40))

oder punktfrei:

f :: Int -> IO [Int]
f = flip replicateM $ randomRIO (1, 40)

Verwandte Artikel


Triangularisieren einer Liste in Haskell

Peter Kagey: Ich bin daran interessiert, eine effiziente Haskell-Funktion zu schreiben triangularize :: [a] -> [[a]], die eine (möglicherweise unendliche) Liste in eine Liste von Listen "trianguliert". Zum Beispiel triangularize [1..19]sollte zurückkehren [[1,

Aufbau einer Beziehung in Alloy

Peter Kriens Im Problem der Essensphilosophen haben wir einen Tisch mit Philosophen und Gabeln. sig P {} sig F {} Für dieses Problem möchte ich die folgende Beziehung, die die Tabelle darstellt: P1 -> F1 F1 -> P2 P2 -> F2 F2 -> P3 P3 -> F3 F3 -> P1 Das heißt

Aufbau einer Adjazenzliste

Spidermarn Ich habe Probleme, die endgültige Ausgabe von zu verstehen for i in edgeList: adjacencyList[i[0]].append(i[0]) im Code unten. Ich habe versucht, Aussagen in jeder Zeile auszudrucken, um sie zu verstehen, bin aber immer noch verwirrt. vertex

Aufbau einer Klasse in Java

Matteo Moroni Ich sollte diese Übung bei der Erstellung einer Klasse durchführen, ich habe hochgeladen, dies ist die Lösung des Professors, in Summe und Produktmethoden können nicht ganz herausfinden, an welcher Stelle und warum "A" verwendet wird. class Vetto

Aufbau einer gemeinsamen Kommunikationsschnittstelle

bitm0de Ich habe Probleme beim Erstellen einer abstrakten Schnittstelle für mehrere Kommunikationstypen mit unterschiedlichen Einstellungen für die Verbindung. Ich möchte in der Lage sein, eine Art Factory zu verwenden, um einen der Kommunikationstypen (USB, S

Aufbau einer mehrdimensionalen Differenzierungsmatrix

MorganD Ich habe versucht, die Matrix D ij zu konstruieren , definiert als Ich möchte es für Punkte zeichnen, die sich bei x i = -cos [ π (2 i + 1) / (2 N )] im Intervall [-1,1] befinden, um folglich Ableitungen einer Funktion zu erhalten. Ich habe jedoch Prob

Aufbau einer deterministischen Einbandmaschine

flink Ich versuche, eine deterministische Turingmaschine zu entwickeln, um Folgendes zu tun: Finde den mittleren Buchstaben eines beliebigen Wortes. Es muss ein Wort als Eingabe nehmen, das nur a und b enthält, und sobald es das mittlere Zeichen gefunden hat,

Umkehren einer Liste in einer anderen Liste in Haskell

ZCoder Ich bin ziemlich neu in Haskell und versuche, eine Liste umzukehren. Gleichzeitig möchte ich die Listen in dieser Liste umkehren. Also zum Beispiel: Prelude> rev [[3,4,5],[7,5,2]] [[2,5,7],[5,4,3]] Ich weiß, dass der folgende Code eine Liste umkehrt: r