2013-06-06 1 views
6

多くの制約が集まっているようです。これらを抽象化しましょう。制約ファミリのための基礎知識

type MonadNumState a m = (MonadState a m, Num a) 

MonadNumStateだけ制約同義語であるので、私は使用するたびに関数従属性の利益を得る、そして簡単にコンテキストにMonadNumState a mを投げることができます。

class Iterator t where 
    type MonadIter t a m :: Constraint 
    next :: (MonadIter t a m) => m t 
    ... 

instance Iterator Foo where 
    type MonadIter Foo a m = (MonadState a m, Num a) 
    ... 

instance Iterator Bar where 
    type MonadIter Bar a m = (MonadRandom m, MonadSplit a m, RandomGen a) 
    ... 

しかし、今aは機能的依存関係ではありません。今、私は制約家族にこの抽象したいとします。 aは推測できないため、nextは事実上使用できません。私に何ができる?もちろん、代わりにタイプファミリーを使用することもできます。 MonadStateはfundepsを使って書かれていますが、基底系を型族に変換するのは簡単です。

instance (MonadState s m) => MonadStateFamily m where 
    type St m = s 
    get' = get 
    ... 

instance (MonadStateFamily m) => MonadState (St m) m where 
    get = get' 
    ... 

Foo.hs:25:3: 
The RHS of an associated type declaration mentions type variable `s' 
    All such variables must be bound on the LHS 

ほかに何ができるでしょうか?私が本当に望んでいるのは、現実的に離れて数値化することです。s。明示的な辞書を渡すことなくこれを行う方法は見つけられていません。

したがって、どのように制約ファミリのための資金の利益を得ることができますか?

答えて

3

あなたが代わりに関連したタイプ

type family StateType (m:: * -> *) 

次にあなたが

class MonadStateFamily m where 
    get' :: m (StateType m) 

instance (MonadState s m, s ~ StateType m) => MonadStateFamily m where 
    get' = get 

を定義し、このようなコンクリートのモナドにそれを使用することができ、スタンドアロン型ファミリを使用することを検討することができます

type instance StateType (State s) = s 
getState :: State s s 
getState = get' 
関連する問題