2016-08-05 15 views
0

は、私は「ものの列」の様々なタイプの型クラスを作成したいので、このような何か:Haskell:データの複数の型変数のインスタンス?

class Column c where 
    at :: c a -> Int -> a 

data ListColumn a = ListColumn { 
    lcContent :: [a] 
} 

instance Column ListColumn where 
    at c i = lcContent c !! i 

今、私は別の1列を導出したいです。私は顧客のコラムを持っているとし、そこから顧客名の列を派生したいと思います。だから私は書いた:

data DerivedColumn a b c = DerivedColumn { 
    dcBase :: c a, 
    dcDerive :: a -> b 
} 

aが顧客であること、上記の例でb顧客名。

instance Column (DerivedColumn a b) where 
    at c i = dcDerive c $ at (dcBase c) i 

しかし、GHCはそれ(Column should have kind * -> *, but DerivedColumn a b has kind (* -> *) -> *を)好きには思えない。今私は、私はこのような何かを書くことができると思いました。誰かが正しい方向を指すことができますか?

+0

ちょっとわかりませんが、コンテナの型が 'a'、最後に' DerivedColumn'の型変数をシャッフルする必要があるようですね。したがって、定義は 'data DerivedColumn c b a = ...'でなければなりません。 'Column'型のクラスは、具体的な型を取得するためにコンテナ型を適用できる型を予期しています。 –

+0

はい、それは意味があります、ありがとう! – martingw

答えて

2

私は何をあなたの代わりにしたいことは、このだと思う:あなたはColumnクラスを見れば、あなたはcは親切* -> *があり、c aaがあることがわかります、ビットを展開するには

data DerivedColumn c a b = DerivedColumn { 
    dcBase :: c a, 
    dcDerive :: a -> b 
} 

instance Column c => Column (DerivedColumn c a) where 
    at dc i = dcDerive $ at (dcBase dc) i 

cに含まれる値の型。 DerivedColumn a b cに含まれる列の値は、b型である必要があります。したがって、実際には、Columnのインスタンスを定義するための型コンストラクタに渡す最後の値にする必要があります。

+0

ありがとう、それは速かったそれは働いて、今私は理由を理解する必要があります: - )... – martingw

+0

私はいくつかの説明を追加しました。あなたに質問がある場合はお知らせください。 – Emil