haskell-problem: io string - [int]

7

Hallo großartige Programmierer da draußen,

Ich mache meine ersten Schritte in Haskell und habe eine Funktion, die mich verwirrt:

%Vor%

splitOneOf ist in Data.List.Split (ich habe es mit cabal install split installiert) splitOneOf :: (Eq a)=> [a]->[a]->[[a]]

Aus dem Fehler geht hervor, dass es eine Art von Ungenauigkeit gibt - aber ich weiß nicht, wie ich diese Konflikte lösen soll, da IO für mich immer noch ein Rätsel ist

Ich möchte eine Eingabe von Ganzzahlen lesen, die durch Kommas oder Semikolons getrennt sind, und eine Liste von ganzen Zahlen erhalten:

  • Wie kann ich überprüfen, ob Benutzereingaben vom Typ Int
  • sind?
  • Wie kann ich die Eingabe, die vom Typ "IO String" ist, in [Int]
  • übersetzen?

danke im Voraus für Gedanken und Hinweise  - Dein ε / 2

    
epsilonhalbe 23.02.2011, 12:16
quelle

4 Antworten

12

Wenn Sie eine Funktion schreiben, die die IO-Monade verwendet, muss jeder Wert, den Sie von der Funktion zurückgeben möchten, auch in der IO-Monade enthalten sein.

Das bedeutet, dass Sie, anstatt einen Wert vom Typ [Int] zurückzugeben, etwas mit dem Typ IO [Int] zurückgeben müssen. Dazu verwenden Sie die Funktion return , die den Wert in IO "einfügt" (er funktioniert tatsächlich für beliebige Monade).

Ändere einfach die letzte Zeile, um deinen Wert mit return zu umhüllen, wie folgt:

%Vor%     
porges 23.02.2011 12:28
quelle
7

Der richtige Weg, um es in Haskell zu machen, ist, IO von, na ja, alles andere zu trennen. Die direkte Übersetzung Ihres Codes wäre dies:

%Vor%

Beachten Sie, dass getncheck_guesslist einfach eine IO-Aktion ist. Die Funktion hat keine Eingabe -Parameter , obwohl sie (IO) -Eingabe von getLine erfordert.

Beachten Sie auch, dass getncheck_guesslist eine einfache Änderung der Aktion getLine IO ist. Gibt es nicht einen Kombinator, der mich eine Funktion auf den Wert innerhalb einer Monade wirken lassen würde? Halt. Hoogle Zeit!

Ich habe eine Funktion (a -> b) . Ich habe einen Wert des Eingabetyps, aber er hängt in einer Monade m a . Ich möchte die Funktion innerhalb der Monade ausführen, so dass das Ergebnis unweigerlich auch in der Monade stecken bleibt m b . Wenn wir das alles zusammenfügen, hoogle (a -> b) -> m a -> m b Und siehe da, fmap ist genau das, was wir gesucht haben.

%Vor%

Als letzte Anmerkung, wenn Sie eine Methode mit dem Namen wie somethingAndSomethingElse codieren, ist es normalerweise besser, wenn Sie something und somethingElse als zwei separate Methoden schreiben und aufrufen. Für die endgültigen Versionen habe ich sie einfach in get_guesslist umbenannt, da dies konzeptuell so ist. Es erhält die Vermutungen als eine Liste von Inten.

Als letzte Schlussnote habe ich an dem Punkt aufgehört, an dem barsoap angefangen hat. ;) fmap ist dasselbe wie <$> .

    
Dan Burton 23.02.2011 18:49
quelle
2

Wenn etwas in der IO monad ist, kannst du es nicht zur reinen Außenwelt zur weiteren Verarbeitung bringen. Stattdessen übergeben Sie Ihre reinen Funktionen an die Funktionen in IO .

Am Ende liest Ihr Programm einige Eingaben und schreibt einige Ausgaben, so dass Ihre Hauptfunktion mit IO arbeitet, sonst können Sie einfach nichts ausgeben. Anstatt IO String zu lesen und eine [Int] zu erstellen, übergeben Sie die Funktion, die diese [Int] verbraucht, in Ihre Hauptfunktion und verwenden Sie sie in do .

    
9000 23.02.2011 12:23
quelle
2
%Vor%

Jedes Mal, wenn der Code auf foo >>= return . bar runterspringt, was Sie tun, indem Sie den do-Block entschuldigen (und den Typ-Fehler korrigieren), benutzen Sie nicht die monadischen Eigenschaften Ihrer Monade, sondern nur deren Funktorteil, das heißt unverblümt gesagt, Sie sind nicht mit dem IO Teil des Typs, aber mit dem a von IO a :

%Vor%

( fmap wäre der Nicht-Infix-Name für <$> . Beide sind eng verwandt mit map .)

Der obige Code ist für Ad-hoc-Code ziemlich idiomatisch, aber sauberer Code würde wie

aussehen %Vor%

, oder alternativ, wenn Sie Nicht-Int-Eingaben nicht ignorieren, sondern Fehler vermeiden möchten,

%Vor%

(Aber Achtung, ich habe nur bewiesen, dass der Code korrekt ist, habe ihn nicht wirklich ausprobiert.)

Wenn es komplizierter wird, sollten Sie eine richtige Parsing-Bibliothek verwenden, denke ich.

    
barsoap 23.02.2011 13:35
quelle

Tags und Links