I want to set the type of the state parameter, of a state monad tranformer, to an associated type of that monad transformer. However, this results in constructing an infinite type,
s = AssocTyp (StateT s m) a
The intuition as to why this isn't really a problem is that,
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a
for all s
and s'
. However, the compiler isn't smart enough to figure this out. I've read that in some cases, a newtype can be used to avoid infinite types; how do I do it?
Here's minimized code to reproduce the question,
{-# 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)
I'm not sure what you're trying to achieve. However, the equality you state,
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a
is not true, because you are using a data family rather than a type family. The following code compiles:
{-# 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
The difference between type families and data families is that data families are injective , which means the following implication holds if DF
is data family:
DF a b c = DF a' b' c' =====> a = a', b = b', c = c'
This is not what you want in your case.
Just in case a data family is what you want, I have a variant that does type check:
isAssocType' :: (Monad m1, Monad m0) => (AssocTyp m1 a) -> m0 ()
isAssocType' _ = return ()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.