Вопрос

У меня есть тип данных, который содержит IOREF в качестве важного элемента. Это означает, что нет чистого способа сделать его членом show Тип класса. Это не так уж плохо, так как у меня есть print Функция в IO Monad для этого типа. Но в GHCI это раздражает, что каждый раз, когда я возвращаю одну из этих вещей в результате, я получаю ошибку, утверждая, что ее нельзя показать.

Есть ли способ получить GHCI, который в любом случае работает в IO Monad, чтобы использовать действие IO, чтобы показать результат? Если нет, то будут ли какие -либо негативные последствия для написания show a = unsafePerformIO $ print a?

Это было полезно?

Решение

Считали ли вы добавить в свой файл .ghci что -то вроде:

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

Это совсем небезопасно, но если это просто для вашего личного использования, возможно, это нормально.

Для более общего использования ранее данные ответы выглядят хорошо для меня. То есть, либо определите статическое «Я не могу показать это» сообщение:

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

Это дало бы что -то вроде:

> runFunc
MyStruct <ioref> 4 "string val"

Или используйте пользовательскую функцию. Я предлагаю сделать класс и поднять все экземпляры шоу:

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

Давая выход (непроверенный, это просто написано вручную):

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

Другие советы

GHCI имеет три случая для возвратных значений:

  1. Show a => a: Просто запустите шоу и распечатайте его
  2. Show a => IO a: Выполните действие, запустите шоу и печати
  3. IO (): ничего не печатайте

Поэтому обычно, если вы вводите действие ввода -вывода, оно выполняется, и результат печатается, если оно не (). Анкет Давай попробуем:

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

Если вы хотите напечатать что -то другое, лучший способ - это написать пользовательскую функцию и прикрепить ее перед каждой строкой, которую вы хотите увидеть:

myShowFun :: ... -> IO String

ghci> myShowFun $ ...
foobar
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top