Ich fange gerade an, Haskell zu lernen, und es ist eine ganz andere Art zu denken als das, was ich gewohnt bin (die C-Stil-Sprachen).
Wie auch immer, für ein Problem, an dem ich gerade arbeite, brauche ich Benutzereingaben. Es wird in der Form
kommen %Vor%zum Beispiel. Format ist die erste Zeile, die die Anzahl der Zeilen angibt, die folgen. Mein erster Gedanke war, dass ich die erste Zeile lesen würde und dann eine Schleife mehrmals ausführen würde. Das ist aber Haskell! Soweit ich weiß, sind Schleifen nicht möglich.
Mein nächster Gedanke war, dass ich die erste Zeile der Eingabe verwenden würde, um eine Liste mit den anderen n Zahlen zu füllen, die folgen. Ich habe keine Ahnung, wie ich das machen würde. Ich bin hier, weil ich nicht einmal sicher bin, nach was ich suchen würde, um es herauszufinden.
Vielen Dank im Voraus, dass Sie mir den Haskell-Weg gezeigt haben, dies zu tun. Es ist schwer, so weit zu gehen, aber ich höre begeisterte Kritiken von Leuten, die "erleuchtet" sind, also denke ich, dass es nicht schaden kann, die Sprache selbst zu lernen.
Hier ist der Code, der einmal gut ausgeführt wird, aber für jede der zweiten bis n Zeilen, die der ersten Zeile folgen, einmal ausgeführt werden muss.
%Vor%(Ich würde auch gerne hören, ob es andere Verbesserungen gibt, die ich an meinem Code vornehmen könnte, aber in diesem speziellen Fall ist es für einen Wettbewerb, ein Problem mit möglichst wenigen Zeichen zu lösen. Ich will nicht um genauer zu werden, falls andere Leute nach einer Antwort auf das gleiche Problem suchen.)
EDIT: Danke für alle Antworten. Irgendwann bekam ich etwas, das sich so benahm, wie ich es wollte. Ich habe den Code für die Nachwelt unten angegeben. Obwohl die Testfälle mit Bravour bestanden, waren die tatsächlichen Daten, an denen sie getestet wurden, anders, und alles, was sie mir sagen, ist, dass ich die "falsche Antwort" bekommen habe. Dieser Code "funktioniert", bringt aber nicht die richtige Antwort.
%Vor%Als Erstes können Sie in haskell eine gute Schleife machen. Es passiert ständig. Sie haben einfach keine syntaktischen Konstrukte dafür, da es keine Notwendigkeit für sie gibt.
Die meisten allgemeinen Schleifen werden in Bibliotheken gespeichert. In diesem Fall befindet sich die benötigte Schleife in den Standardbibliotheken im Modul Control.Monad
. Es heißt replicateM
. Es hat die Typensignatur Monad m => Int -> m a -> m [a]
. Um diese Signatur für Ihren Fall zu spezialisieren, hätte sie den Typ Int -> IO Int -> IO [Int]
. Das erste Argument ist die Anzahl der Schleifen. Die zweite ist die IO-Aktion, die in jeder Schleife ausgeführt wird. Das Ergebnis der Funktion ist eine IO-Aktion, die die Liste der Eingaben erzeugt.
Wenn Sie beispielsweise inputs <- replicateM b readLn
zu Ihrem do-Block hinzufügen, wird eine Liste mit dem Namen inputs
in den Bereich eingefügt, die die Werte aus den b
-Zeilen enthält, die der ersten folgen. Sie könnten dann Ihre Lösungsfunktion über diese Zeilen abbilden.
Carls Lösung wird funktionieren, aber es ist etwas undurchsichtig. Wenn du es schreiben willst, könntest du so etwas machen:
%Vor% Was Sie hier mit readLines
tun, ist, dass Sie im Wesentlichen den offensichtlichen Grundfall definieren (um 0 Dinge zu lesen, geben Sie einfach eine leere Liste) und den rekursiven Fall (um n Dinge zu lesen, lesen Sie dann eine Sache lies die anderen n-1 Dinge und kombiniere sie dann miteinander).
Ich bin mir nicht sicher, was genau Sie tun möchten, aber um eine Ganzzahl n und dann die nächsten n Zeilen als Ganzzahlen zu lesen, könnten Sie etwas tun wie:
%Vor% Das return $ sum xs
am Ende des Kurses ist nicht wesentlich - wenn es nicht dort wäre, würden Sie eine explizite Typ-Signatur für test
benötigen.
Wenn Sie keine dieser Funktionen verstehen, hoogle .
Sie könnten ein readInput n
erstellen, wobei n
die Anzahl der zu lesenden Zeilen ist. Der Aufruf dies rekursiv 1 von n
jedes Mal subtrahieren. Ich bin auch ein Haskell-Noob, also ist das vielleicht nicht der beste Ansatz. Es sollte trotzdem funktionieren.
Tags und Links haskell