我想要将状态单体转换器的状态参数的类型设置为该单体转换器的关联类型。然而,这会导致构造一个无限类型,
s = AssocTyp (StateT s m) a为什么这不是真正的问题的直觉是,
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a用于所有s和s'。然而,编译器还不够聪明,不能解决这个问题。我读到过,在某些情况下,新类型可以用来避免无限类型;我该怎么做?
下面是重现问题的最小化代码,
{-# 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)发布于 2012-03-27 07:53:23
我不知道你想要达到什么目的。然而,你所说的平等,
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类型族和数据族之间的区别在于data families are injective,这意味着如果DF是数据族,则以下含义成立:
DF a b c = DF a' b' c' =====> a = a', b = b', c = c'这不是你想要的情况。
发布于 2012-03-27 07:58:26
如果数据系列是您想要的,我有一个执行类型检查的变体:
isAssocType' :: (Monad m1, Monad m0) => (AssocTyp m1 a) -> m0 ()
isAssocType' _ = return ()https://stackoverflow.com/questions/9880709
复制相似问题