2012-04-02 19 views
7

基本的な考え方は、特定のクラスのあらゆる型で機能するさまざまな関数を持っていますが、実行時にプログラムは構成ファイルを読み込み、クラス内の型の動的型定義の特定の形式を明示的に実装する

たとえば、「係数」クラス、そのさまざまなインスタンス、およびそのクラスのタイプに対して多型のさまざまなタイプの関数があります。実行時にそのクラスの1つの特定の型が決定され、渡される。


私はこれに適切に対処する方法がわかりません。

ここで、Int、Double、...はクラス '係数'のインスタンスです。
しかし、コードに含まれるすべての関数をこれらの複合型で動作させるために大きな努力が払われ始めました(実際には素晴らしい解決策ではありません)。すべての機能が同じで簡単なタイプのものであればOKです。

Coefficient a => a -> (stuff not involving a anymore) 

しかし、残念ながらそうではありません。

私はに走ったもう一つの問題は、私は次のように、タイプファミリを使用して、と私は化合物ColourDataデータ型のいくつかの並べ替えを使用する必要があればこれがきれいに通過しない

class (Monoid (ColourData c), Coordinate (InputData c)) => ColourScheme c where 
    type ColourData c :: * 
    type InputData c :: * 
    colouriseData  :: c -> (ColourData c) -> AlphaColour Double 
    processInput  :: c -> InputData c -> ColourData c 

のようなものを持っているんだということです前のもの。特に、データストリームが一貫性のあるタイプ(複合型の異なるサブタイプではない)だけでなく、(他のものの中でも)偽のMonoidインスタンスを構成しなければならないことは、もはや保証できません。複合ColourData型。

私はData.Dynamicについても見てきましたが、問題を適切に解決する方法がわかりません。まったく同じ問題が発生しているようです(私が理解しているように「ジェネリック」のダイナミックタイプが1つしかないことを考えると、少し悪化します)。


質問:はどのように私はこれらのデータ型を含むすべての機能を書き換えることなく、特定のクラスに従属する動的なデータ型を実装することができますか?どんなタイプの安全性も犠牲にする必要がないなら、私は楽観的ではありません。
プログラムは、実行時に構成ファイルを読み込み、関連するクラスの多型であるすべての必要な関数を適用することになっています。より読みやすいかもしれませんGADTs、と、

{-# LANGUAGE ExistentialTypes #-} 
data SomeFoo = forall a . Foo a => SomeFoo a 

instance Foo SomeFoo where 
    -- all operations just unwrap the SomeFoo straightforwardly 

か:

答えて

7

それは型クラスFooのインスタンスですが、追加の保証を行うものではありませんことを保証オブジェクトを提供するために、従来の方法は、そうのようなものです。 ..

topLevel :: SomeTypeClass a => a -> IO() 

あなたのプログラムは、このような何かを書くことができます:一つの提案は、あなたがタイプを選択したら、すべての最後の仕上げを行い、単一のトップレベルの関数を書くことであろう

data SomeFoo where 
    SomeFoo :: Foo a => a -> SomeFoo 
6

main = do 
    config <- readConfig 
    case config of 
     UseDouble n -> topLevel n 
     UseSymbolic x -> topLevel x 
     UseWidgetFrobnosticator wf -> topLevel wf 
関連する問題