2012-03-26 7 views
1

状態モナドトランスフォーマーの状態パラメータのタイプを、そのモナドトランスの関連タイプに設定したいとします。しかし、これは無限の種類を構築することになる、これは本当に問題ではありません理由としてhaskell - この無限の型を避けるにはどうすればいいですか? (関連するデータとStateT)

s = AssocTyp (StateT s m) a 

直感はすべてss'ため

AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a 

、ということです。しかし、コンパイラはこれを理解するほどスマートではありません。いくつかのケースでは、無限型を避けるためにnewtypeを使うことができます。どうすればいいのですか?ここで

{-# LANGUAGE KindSignatures, TypeFamilies #-} 

import Control.Monad.Trans.State 

class MyMonad (m :: * -> *) where 
    data AssocTyp m :: * -> * 

instance MyMonad m => MyMonad (StateT s m) where 
    data AssocTyp (StateT s m) a = StateTA (AssocTyp m a) 

isAssocTyp :: Monad m => (AssocTyp m a) -> m() 
isAssocTyp x = return() 

x = do 
    v <- get 
    isAssocTyp (v) 

答えて

2

は、私はあなたが達成しようとしているかわからないんだけど、問題を再現するコードを最小限に抑えています。あなたはデータ家族ではなく、タイプ家族を使用しているので、しかし、あなたは状態平等、

AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a 

は、真実ではありません。次のコードはコンパイルされます。

{-# LANGUAGE KindSignatures, TypeFamilies #-} 

import Control.Monad.Trans.State 

class MyMonad (m :: * -> *) where 
    type AssocTyp m :: * -> * 

instance MyMonad m => MyMonad (StateT s m) where 
    type AssocTyp (StateT s m) = AssocTyp m 

isAssocTyp :: Monad m => (AssocTyp m a) -> m() 
isAssocTyp x = return() 

x :: Monad m => StateT (AssocTyp m a) m() 
x = do 
    v <- get 
    isAssocTyp v 

タイプの家族やデータ家族との差がDF場合は、次の含意は成立する意味data families are injectiveは、データ・ファミリであるということです。

DF a b c = DF a' b' c' =====>  a = a', b = b', c = c' 

これはあなたが望むものではありませんあなたの場合。データ家族が何をしたいです念のために

+0

ああ、どうもありがとうございました!!私はタイプレベルとデータレベルで平等を混同していると思います。 – gatoatigrado

0

、私は型チェックんバリアントを持っています。

isAssocType' :: (Monad m1, Monad m0) => (AssocTyp m1 a) -> m0() 
isAssocType' _ = return() 
+0

申し訳ありませんが、「isAssocType」が減少しました(例として)。 – gatoatigrado