2016-09-15 11 views
1

私は次のような問題があります。タイプクラスを定義し、このクラスのタプルをインスタンスとして宣言したいと考えています。しかし、私はGHCにこの宣言を受け入れる方法を知らない。ここでは非常に簡単な例:タイプクラスに属するコンポーネントとタプルを作る方法インスタンス

class Test a where 
    elm :: a 

そして、私は

instance (Test a, Test b) => Test (a,b) where 
    elm = (elm, elm) :: (a,b) 

のような何かをしたいタプルのために知っている(実際には、私はベクトル空間に対応し、より派手なタイプのクラスに対して同様の何かをしたいです。)

どうすればいいですか?事前に感謝の意を表します!

+3

'::(a、b)'を削除します。 –

+0

ありがとう!できます!私は型の注釈なしでそれを最初に試していましたが... – dmw64

答えて

8

代わりにこれを試してみてください:これは動作するはず

instance (Test a, Test b) => Test (a,b) where 
    elm = (elm, elm) 

。あなたのコードに関する問題は、追加した:: (a,b)タイプのアノテーションが、実際に助けてくれる代わりにGHCを混乱させるということです。問題は、GHCがabを見ると、それらが何らかの任意のタイプを表していると考えていることです。しかし、それらを恣意的にしたくない場合は、上記の行で参照されているのとまったく同じ型にしてください。しかし、GHCはそのことを知らない。型注釈をそのまま残しておけば、GHCは正しい型を把握します。また、あなたは、ファイルの先頭に以下を追加することにより、ScopedTypeVariables言語拡張を可能にすることによって、GHCの振る舞いを変更することができます。

{-# LANGUAGE ScopedTypeVariables #-} 

これはGHCを教えてくれることclass定義、で参照型変数があるたびにトップラインは、定義の残りの範囲になります。私はScopedTypeVariablesがデフォルトでオンになっていたはずだと思う人々の1人ですが、残念なことにこれはそうではありません。ほとんどの場合、互換性の理由から歴史的には&です。実際には、この質問は、なぜScopedTypeVariablesがデフォルトでオフになっているのが、直観に反するものであるという良い議論を提供します。

+0

ありがとう!できます!私は型の注釈なしで最初に試していましたが... – dmw64

関連する問題