-
26-10-2019 - |
質問
重要な要素としてIOREFを含むデータ型があります。これは、それをのメンバーにするためのクリーンな方法がないことを意味します show
タイプクラス。私が持っているので、これはそれほど悪くはありません print
このタイプのIO Monadの関数。しかし、GHCIでは、これらのことの1つを返すたびに、表示できないことを示すエラーが発生するという点で迷惑です。
とにかくIO Monadで動作するGHCIを取得する方法はありますか?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には、戻り値の3つのケースがあります。
Show a => a
: :ショーを実行して印刷するだけですShow a => IO a
: :アクションを実行し、ショーを実行して印刷しますIO ()
: :何も印刷しません
したがって、通常、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
所属していません StackOverflow