2016-05-09 4 views
0

PureScriptにReduxのようなストアを書き込もうとしています。このタイプのクラスインスタンスが統合に失敗したのはなぜですか?

私はAction型クラスを定義し、各アクションの代数データ型をより小さなモジュールに分割しました。

class Action a 

data FooAction 
    = UpdateFoo String 
    | ResetFoo 

data BarAction 
    = UpdateBar Int 
    | ResetBar 

data ResetAll = ResetAll 

instance fooAction :: Action FooAction  
instance barAction :: Action BarAction 

いくつかの状態タイプと更新関数を定義しました。更新機能は、すべてのタイプのアクションを受け取ることがあります。

newtype Foo = Foo String 
newtype Bar = Bar Int 

updateFoo :: forall a. (Action a) => a -> Foo -> Foo 
updateFoo a foo = 
    case a of 
    UpdateFoo str -> Foo str 
    ResetFoo  -> Foo "" 
    ResetAll  -> Foo "" 
    _    -> foo 

updateBar :: forall a. (Action a) => a -> Bar -> Bar 
updateBar a bar = 
    case a of 
    UpdateBar num -> Bar num 
    ResetBar  -> Bar 0 
    ResetAll  -> Bar 0 
    _    -> bar 

しかし、このコードはTypesDoNotUnifyエラーを生成します。

Could not match type 

    FooAction 

    with type 

    a0 


while checking that expression case a of 
           (UpdateFoo str) -> Foo str 
           ResetFoo -> Foo "" 
           ResetAll -> Foo "" 
           _ -> foo 
    has type Foo 
in value declaration updateFoo 

where a0 is a rigid type variable 

このエラーはなぜ発生しますか?このような更新機能はどのように実装すればよいですか?

答えて

0

ここで問題となるのは、値Action a => aFooのように一致しているため、タイプエラーです。

あなたが問題を解決するためのクラスを使用する場合は、アプローチはかなり異なるタイプのデータ構築よりも、クラスのアクション部分を作るために次のようになります。

class Thing a 
    update :: a -> String 
    reset :: a -> Unit 

そして、あなたはupdateかを呼び出すことができますresetFoo,Bar,Bazと入力するか、Thingインスタンスを実装するすべての型指定値を使用します。

問題は、あなたが、あなたはあまりにもサブクラスを使用することができ、これらの事が実行できる操作の異なるセットを表現したい場合には:

class Thing a <= SubThing a 
    act :: a -> Unit 

私は、私は非常にあなたがしようとしているものを理解していませんしかし、おそらくこれはあなたが後にしていることではないかもしれませんが、うまくいけばあなたにいくつかのアイデアを与えるでしょう。

+0

ありがとうございました!型クラス関数とパターンマッチングを使用します。 – katashin

関連する問題