質問

重要な要素として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つのケースがあります。

  1. Show a => a: :ショーを実行して印刷するだけです
  2. Show a => IO a: :アクションを実行し、ショーを実行して印刷します
  3. 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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top