2011-10-22 15 views
3

以下はHaskellの多型データ型で、Hugsによって解釈されます。 Show for Equalityのインスタンスを作成しようとしています。Haskell(Hugs)のこのShowインスタンスがスタックオーバーフローエラーを引き起こすのはなぜですか?

インスタンス宣言では、「a」タイプが「表示」にある場合、「等価」aが「表示」に表示されます。コンストラクタの2つの引数をaとbをa = bの形式で出力する必要があります。

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where 
show (Equals a b) = a ++ " = " ++ b 

しかし、 "(平等9 9)" のような抱擁に何かを入力利回り:

ERROR - Cのスタックオーバーフロー

だから、私は「ショーを(A-Bに等しい)インデントみました。.. 。 "行に2つのスペースがあります。私は違いがどうなるかわからないんだけど、ただ遊んでた後、これを得た:これらのエラーが発生し、またはこのショーのインスタンスを実装するより良い方法を提案している理由

Inferred type is not general enough 
*** Expression : show 
*** Expected type : Show (Equality a) => Equality a -> String 
*** Inferred type : Show (Equality [Char]) => Equality [Char] -> String 

誰も説明できますか?

ありがとうございました!

+0

は、これは一般的に悪い考えです: 'Show'は、有効なHaskellコード(モジュロインポートの詳細を生成、Haskellのための基本的な直列化機構を提供するためのものです)。カスタム出力フォーマットを行いたい場合は、複雑な出力用にきれいな印刷ライブラリを使用して、カスタムの 'prettyPrint :: a - > String'関数などを生成することができます。 – ivanm

答えて

1

インデントが原因Haskellので-回-奇妙な空白感度に問題ありません。字下げがなければ、コンパイラは次の文がwhereに属することを認識できません。

エラーは、制約を持たない多態型で、abが「=」文字列と連結できるためです。 Equals 1 1の場合はどうなりますか?インツの文字列を最初に作ることなく、どのように連結しますか?

ただし、show aとbを最初に使用すると、すべてが正しく動作します。showは、値を文字列に連結できるものにマートします。

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where 
    show (Equals a b) = (show a) ++ " = " ++ (show b) 
+0

ああ。私はその周りをしばらく踊っていたが、それをまとめて入れることはできなかった。明確で、詳細で、肯定的な回答をいただきありがとうございます。 – Cody

+2

'(show a)'と '(show b)'の周囲の括弧を安全に削除することができます –

+1

インデント規則が奇妙だとは言いません...もしこの行が何かに属していれば、それ以上インデントしてください! – ivanm

1

あなたの問題は、あなたが引数abに関数showをコールしなかったことです。私はGHCでこれをやったが、私はそれが動作するはずだと思う:

その後
data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where 
    show (Equals a b) = show a ++ " = " ++ show b 

> Equals 9 9 
9 = 9 
3

コードが間違ってインデントされています。

instance (Show a) => Show (Equality a) where 

show別トップレベルの機能:タイプEquality [Char] -> [Char]

show (Equals a b) = a ++ " = " ++ b 

、空Showインスタンスを定義します。したがって、Showインスタンスを使用しようとすると、default definition of show from the Show classが取得されます。コードを見てみると:

showsPrec _ x s = show x ++ s 
show x   = showsPrec zeroInt x "" 

がデフォルトshowは、showsPrecの観点で定義されている順番にshowの観点から定義されていることがわかります。これは、あなたのプログラムが無限ループに入る理由を説明します。あなたがaを変換する必要があります - 、コードを修正し、適切にそれをインデントし、あなたが文字列を使用して、任意のタイプaを連結することができないという事実から生じるタイプのエラーを(修正するshowに欠けているの呼び出しを追加するには

最初の文字列):

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where 
    show (Equals a b) = show a ++ " = " ++ show b 

テスト:

*Main> show (Equals 9 9) 
"9 = 9" 
関連する問題