[英]haskell — How to avoid this infinite type? (Associated data and StateT)
我想将状态参数(状态monad转换器)的类型设置为该monad转换器的关联类型。 但是,这导致构造无限类型,
s = AssocTyp (StateT s m) a
关于为什么这不是一个真正的问题的直觉是,
AssocTyp (StateT s m) a = AssocTyp (StateT s' m) a
对于所有的s
和s'
。 但是,编译器不够聪明,无法解决这个问题。 我读过在某些情况下,可以使用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)
我不确定你想要实现的目标。 但是,你所说的平等,
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
是数据族,则以下含义成立:
DF a b c = DF a' b' c' =====> a = a', b = b', c = c'
这不是你想要的。
如果数据系列是你想要的,我有一个类型检查的变体:
isAssocType' :: (Monad m1, Monad m0) => (AssocTyp m1 a) -> m0 ()
isAssocType' _ = return ()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.