2013-05-08 4 views
7

私は、次の型クラスを使用しています:2つのモジュールから同じインスタンスをインポートしないようにHaskellに指示するには?

module T where 
class T a where 
    v :: a 

私が実装T Intのインスタンス:

import T 
import A (av) 

instance T Int where 
    v = 0 

main = putStrLn (av ++ show v) 

そして、私はまたのインスタンスを持っているから値を、使用したいモジュールをT Int

module A where 
import T 
instance T Int where 
    v = 0 
av = "value from A" 

問題は、これが動作しないです。

$ runghc Main.hs 

Main.hs:4:9: 
    Duplicate instance declarations: 
     instance T Int -- Defined at Main.hs:4:9-13 
     instance T Int -- Defined at A.hs:3:9-13 

Haskellは同じインスタンスのための2つの宣言があると文句を言い。 Bからインスタンスをインポートしないように、または両方のインスタンスを統合するように、またはMainのインスタンスのみを使用するように指示するにはどうすればよいですか。

+1

これを行わないでください。適切な解決策は、インスタンスを1つの場所に宣言することだけです。 – hammar

+0

@ハマー: 'T'や' B'は書きませんでしたが、 'B'の値を使いたいと思い、' T'のインスタンスを作りたいと思います。 – Dog

+1

ああ、それはやっかいです。その場合、既存の型をラップする 'newtype'を作成し、代わりに' newtype'のインスタンスを書くことができます。 – hammar

答えて

8

残念ながら、インスタンスのインポートとエクスポートの方法を制御することはできません。 Do Haskell imports have side effects?を参照してください。

これは、インスタンスが1つのファイルでのみ定義されるように、コードをリファクタリングする必要があることを意味します。一般に、クラスまたはデータ型のいずれかを定義するファイル内のインスタンスのみを定義するのが最善です。実際には、このルールに従わない「孤立した」インスタンスについての警告さえあります。

ただし、これが何らかの理由で不可能な場合でも、ファイルを保持するために任意に選択することも、新しいモジュールを作成することもできます(詳細はOrphaned instances in Haskellを参照してください)。その特定のインスタンスを必要とするすべてのファイルによってインポートされます。あなたは2つのインスタンスのような異なる事を、やったという可能性に対処する方法をより一般的に

、これら両者を明確にするために本当にありませんすぐに明らかな方法が大幅にHaskellの方法を変更することなく、ある

instance T Int where v = 0 
{- And in a different file: -} 
instance T Int where v = 1 

typeclassシステムが動作します。

インスタンスの1つを自分で書きましたので、削除するだけです。あらかじめ定義されているモジュールと同じなので、モジュールを使用する必要がある場合は、そのモジュールをインポートしてください。

+0

"これは、インスタンスが1つのファイルでのみ定義されるように、コードをリファクタリングする必要があることを意味します。これどうやってするの?私は 'T'や' B'を書かなかった。 – Dog

+0

ああ。ええ、それは悪いです。このため、孤立したインスタンスを作成するはずがありません。私は孤立したインスタンスを持っているモジュール、つまりクラスまたは型を定義しないインスタンスを持つモジュールでこれに関するバグを報告します。 –

+2

@ドッグ:実際には、私はあなたの問題を誤解しているかもしれません。あなたがインスタンスの1つを書いたので、単純にインスタンスを削除してください。あなたがする必要があれば 'newtype'のためにそれを書いてください。 –

関連する問題