Frage

Ich habe einen Datentyp, der ein IOREF als wichtiges Element enthält. Dies bedeutet, dass es keinen sauberen Weg gibt, um es zu einem Mitglied der show Geben Sie Klasse ein. Das ist nicht schlecht, da ich eine habe print Funktion im IO -Monad für diesen Typ. Bei GHCI ist es jedoch ärgerlich, dass ich jedes Mal, wenn ich eines dieser Dinge zurückgibt, einen Fehler, der besagt, dass es nicht angezeigt werden kann.

Gibt es eine Möglichkeit, GHCI zu bekommen, der sowieso in der IO -Monadin arbeitet, um eine IO -Aktion zu verwenden, um ein Ergebnis zu zeigen? Wenn nicht, gäbe es negative Konsequenzen für das Schreiben show a = unsafePerformIO $ print a?

War es hilfreich?

Lösung

Haben Sie darüber nachgedacht, Ihre .ghci -Datei hinzuzufügen, so etwas wie:

instance (Show a) => Show (IORef a) where
    show a = show (unsafePerformIO (readIORef a))

Es ist überhaupt nicht sicher, aber wenn dies nur für Ihren persönlichen Gebrauch ist, ist das vielleicht in Ordnung.

Um allgemeiner zu verwenden, sehen Sie die zuvor gegebenen Antworten für mich gut aus. Das heißt, entweder definieren Sie eine statische "Ich kann diese" -Meldung nicht zeigen:

instance Show (IORef a) where
    show _ = "<ioref>"

Dies würde so etwas geben wie:

> runFunc
MyStruct <ioref> 4 "string val"

Oder verwenden Sie eine benutzerdefinierte Funktion. Ich schlage vor, eine Klasse zu erstellen und alle Showinstanzen zu heben:

class ShowIO a where
    showIO :: a -> IO String

instance Show a => ShowIO a where
    showIO = return . show
instance ShowIO a => ShowIO (IORef a) where
    showIO a = readIORef a >>= showIO

Wenn Sie die Ausgabe geben (ungetestet, ist dies nur handgeschrieben):

> myFunc >>= showIO
MyStruct "My String in an IORef" 4 "string val"

Andere Tipps

GHCI hat drei Fälle für Rückgabewerte:

  1. Show a => a: Führen Sie einfach Show aus und drucken Sie sie aus
  2. Show a => IO a: Führen Sie die Aktion aus, führen Sie Show aus und drucken Sie sie
  3. IO (): Drucken Sie nichts

Wenn Sie also eine IO -Aktion eingeben, wird normalerweise ausgeführt und das Ergebnis wird gedruckt, wenn dies nicht der Fall ist (). Lass es uns versuchen:

ghci>15
15
ghci>'a' : 'b' : 'c' : []
"abc"
ghci>putStrLn "Hello, world!"
Hello, world!
ghci>putStrLn "Hello, world!" >> return 42
Hello, world!
42
ghci>

Wenn Sie etwas anderes ausdrucken möchten, besteht der beste Weg wahrscheinlich, eine benutzerdefinierte Funktion zu schreiben und sie vor jede Zeile zu stecken, die Sie sehen möchten:

myShowFun :: ... -> IO String

ghci> myShowFun $ ...
foobar
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top