Question

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)
Was it helpful?

Solution

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.

OTHER TIPS

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 ()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top