2012-09-13 6 views
5

を派生します。すべてのConfigurationインスタンスを強制的に強制して、data Pigdata Cowの実装がすべてShowのインスタンスであることを確認する方法はわかりません。保証は、私は次のようなものを持っている特定のクラス

showPigshowCowの方法があり、複合体全体を書き出すことができるのは分かりますが、実際にはこれより複雑でかなり苦しいです。

タイプファミリーインスタンス自体が特定のクラスのインスタンスであることを保証する簡単で洗練された方法はありますか?

+1

'LANGAUGE'行のために失敗しませんか? –

+1

これはファイル全体ではありません。私はこの質問の目的のためにそれを守った。明らかに、モジュール宣言、ParserCombinators.Parsecインポートなどがあります。 – So8res

+2

私はマットが、LANGUAGEと言っている間、LANGUGEと言っているという事実を意味していたと思います。 –

答えて

8

StandaloneDerivingを使用して、Showインスタンスの制約を手動で指定することができます。

{-# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #-} 
deriving instance (Show (Pig c), Show (Cow c)) => Show (Farm c) 

これはまだあなたがいる限り、あなたがshowにそれらを試していないとして、しかし、Showを実装していないCowPigConfigurationインスタンスを持つようになります。

1

あなたはConfigurationのすべてのインスタンスがPig cCow cShowを実装持ってたいと言っているので、これを行うにしても簡単な方法は、単純にそうように、クラスのコンテキスト内で型家族を制限することです:

{-# LANGUAGE TypeFamilies, FlexibleContexts #-} 

class (Show (Pig c), Show (Cow c)) => Configuration c where 
    data Pig c 
    data Cow c 

data Farm c = Farm { pigs :: [Pig c], 
        cows :: [Cow c] } deriving (Show) 

EDIT:@hammarは彼のコメントで指摘したように

、以前のコードはコンパイルされません。これを解決する方法の1つは、StandaloneDerivingを使用することです。他の方法はこれです:

​​

これらの2つのアプローチは、あなたがshowを呼び出す場合、私のアプローチは可能な制約となります一方、その@のHAMMARのアプローチでは、Configuration制約が必要になり、あなたにわずかに異なる結果が得られます。

+1

これはコンパイルされません(少なくともGHC 7.4.1を使用)。しかし、これを 'StandingoneDeriving'アプローチと組み合わせると'インスタンスの設定を引き出す 'c => Show(Farm c)'は 'UndecidableInstances'の必要性を避けます。 – hammar

関連する問題