Question

I ont un type de données qui contient un IORef comme un élément important. Cela signifie qu'il n'y a pas une manière propre à en faire un membre de la classe de type show. Ce n'est pas trop mal que j'ai une fonction print dans la monade IO pour ce type. Mais il est gênant dans GHCi en ce que chaque fois que je retourne une de ces choses à la suite je reçois une erreur indiquant qu'il ne peut pas être affichée.

Y at-il un moyen d'obtenir GHCi, qui fonctionne dans la monade IO de toute façon, d'utiliser une action IO pour afficher un résultat? Dans le cas contraire, aurait-il des conséquences négatives pour l'écriture show a = unsafePerformIO $ print a?

Était-ce utile?

La solution

Avez-vous envisagé d'ajouter à votre fichier .ghci quelque chose comme:

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

Il est pas sûr du tout, mais si cela est juste pour votre usage personnel peut-être est OK.

Pour une utilisation plus générale les réponses déjà données me semblent bonnes. C'est, soit définir une statique « Je ne peux pas montrer » message:

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

Cela donnerait quelque chose comme:

> runFunc
MyStruct <ioref> 4 "string val"

Ou utiliser une fonction personnalisée. Je suggère faire une classe et la levée de toutes les instances Afficher:

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

Donner la sortie (non testé, ce n'est écrit à la main):

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

Autres conseils

ghci a trois cas pour les valeurs de retour:

  1. Show a => a: Il suffit de lancer show et l'imprimer
  2. Show a => IO a: Exécutez l'action, exécutez visualiser et imprimer
  3. IO (): rien d'impression

Donc, en général, si vous tapez une action IO, il get exécuté et le résultat est imprimé si ce n'est pas (). Essayons:

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

Si vous voulez imprimer quelque chose de différent, la meilleure façon est probablement écrire une fonction personnalisée et le coller devant chaque ligne que vous voulez voir:

myShowFun :: ... -> IO String

ghci> myShowFun $ ...
foobar
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top