2

ここに私が取り組んでいるコードの簡略化されたバージョンがあります

data ArithExp = Con Int
          | Add ArithExp ArithExp

instance Show ArithExp where
          show (Con i)     = show i
          show (Add e1 e2) = show "( " ++ show e1 ++ " + " ++ show e2 ++ " )"

したがって、コマンドを実行すると

Add (Con 6) (Con 0)

私が望む出力は次のとおりです。

( 6 + 0 )

しかし、上記のコードは以下を出力します:

"( "6 + 0 )

私が知る限り、show 関数は最初の文字列の引用符を文字として出力していますが、その後の連結ではそれらを正しく使用しています。振る舞いは私には本当に矛盾しているようです。適切な出力を得るのに役立つ洞察をいただければ幸いです。前もって感謝します!

4

2 に答える 2

10

(Add e1 e2)ブランチshowでは よりも緊密にバインドされているため(++)、コードはより括弧付きで、

show (Add e1 e2) = (show "( ") ++ (show e1) ++ " + " ++ (show e2) ++ " )"

秘訣は、その先頭は実際には必要ないということです---文字列を直接生成していて、 andに再帰的に適用showするだけで済みます。showe1e2

show (Add e1 e2) = "( " ++ show e1 ++ " + " ++ show e2 ++ " )" 
于 2013-09-16T02:37:07.280 に答える
0

一般に、showは、データを ghci に入力した場合に同等のデータ値に評価されるような方法でデータを出力しようとします。文字列の場合、それが何を意味するか考えてみてください。Haskell が評価する式ではなく文字列として解釈するように、文字列値をどのように入力しますか?

これは、私が何を意味するかを示す ghci セッションのサンプルです。

> let myString = "Hello"
> putStrLn $ show myString
=> "Hello"
> :t "Hello"
=> "Hello" :: String
> putStrLn myString
=> Hello
> :t Hello
=> Not in scope: data constructor 'Hello'

コンストラクター式ではなく文字列として評価されるように、もともと文字列を引用符で囲んで入力する必要があったため、 はそれをshow引用符で囲み、値を ghci に貼り付けて、コンストラクター値の代わりに文字列値を取得できるようにします。

の動作は、あなたの例では少し直感に反するようにshow見えるかもしれませんが、実際にはその動作は非常に一貫しています。なぜこのように動作するのかを知ることで、将来このような問題に遭遇するのを避けることができます!

于 2013-09-16T17:46:20.283 に答える